Reference · 005 · 打印友好 · 配套 Lesson 0010
限流算法速查表
四种算法对比
| 算法 | 机制 | 优点 | 缺点 |
|---|---|---|---|
| 固定窗口 | 每周期一个计数器(如每分钟 100),超限拒绝 | 实现最简单,O(1) 内存 | 边界突刺:周期交界瞬间可过 2 倍流量 |
| 滑动窗口日志 | 记录每个请求时间戳,窗口内计数超限拒绝 | 最精确 | 内存 O(窗口内请求数),高 QPS 下昂贵 |
| 滑动窗口计数 | 前后两个固定窗口按当前时间位置加权插值 | 精度与内存的折中 | 是「估算」,极端边界仍有小误差 |
| 令牌桶 ✅ | 恒速放令牌入桶(容量 S),请求取一枚,无令牌则拒 | 允许受控突发;参数直观(速率 r + 桶深 S);工业首选 | 突发期可能压到下游(配 S 时要想清楚) |
| 漏桶 | 请求入桶,以恒定速率流出处理,桶满拒绝 | 把输出流量削成恒速,保护脆弱下游 | 无法利用突发空闲容量;排队增加延迟 |
一句话选择:对外 API / 用户限频 → 令牌桶;保护脆弱的下游服务(如慢速第三方)→ 漏桶;监控类粗限 → 固定窗口先顶上。
分布式限流的实现要点
- 「每实例限 100」≠「全局限 1000」:流量不均时全局限会失真——单机粗限 + 全局精调双层结构
- 全局计数放 Redis:
INCR key+EXPIRE(固定窗口);令牌桶用 Lua 脚本保证「读-判-扣」原子 - 代价链:引入 Redis 依赖 → Redis 挂时限流失效 → 决定「fail-open(放行)还是 fail-closed(拒绝)」要提前定:多数场景 fail-open + 单机兜底限
- 响应规范:HTTP
429 Too Many Requests+Retry-After头 +X-RateLimit-*剩余额度头 - 分级策略:按用户/按 API key/按 IP 分层配额;付费用户配额更高——限流即产品能力
令牌桶伪代码
# 参数:rate(每秒令牌数), capacity(桶深)
# 每次请求:
elapsed = now - last_refill
tokens = min(capacity, tokens + elapsed * rate)
last_refill = now
if tokens >= 1:
tokens -= 1
return ALLOW
else:
return REJECT(429, retry_after = (1 - tokens) / rate)