限流算法对照
四种常见算法:固定窗口、滑动窗口、漏桶、令牌桶。选型看「要不要允许突发」和「实现复杂度」。
1. 固定窗口
单位时间切成互不重叠的窗口,窗口内计数,超限拒绝。
| 优点 | 实现极简单 |
| 缺点 | 临界突刺:窗口末 + 下一窗口初各打满,瞬时可接近 2 倍阈值 |
适合:粗粒度、要求不高的防护。
2. 滑动窗口
把大窗口拆成多个小格,按时间滑动丢掉过期格,统计仍落在窗口内的请求数。
| 优点 | 缓解固定窗口临界问题;格子越细越平滑 |
| 缺点 | 到阈值后通常直接拒,突发友好度一般;格越多状态越多 |
适合:要更准的「每秒 N 次」类配额。
3. 漏桶(Leaky Bucket)
请求进桶排队,以恒定速率流出;桶满则丢弃/拒绝。
| 优点 | 出口速率平滑,利于保护下游 |
| 缺点 | 突发也被抹平,用户侧可能感觉「一直匀速、加速不了」;要缓存队列 |
适合:需要严格平滑、下游能力固定的链路。
4. 令牌桶(Token Bucket)
桶内按速率放令牌,请求消耗令牌;桶空则拒绝。桶有容量 → 允许一定突发。
| 优点 | 平均速率可控,又能吃短时尖峰;Guava RateLimiter 等常见实现 |
| 缺点 | 实现与调参比窗口类复杂;系统时钟异常会影响观感 |
适合:多数业务 API 限流(既要护系统,又不愿完全抹平突发)。
怎么选(极简)
只要粗防刷、实现要快 → 固定窗口
要更准的时间窗计数 → 滑动窗口
下游必须匀速、宁可排队 → 漏桶
平均限速 + 允许短突发 → 令牌桶(默认优先考虑)
分布式下还要叠:网关/Redis 计数、集群一致性、用户/IP/接口多维度配额——算法只是本地或单点策略的核心。