限流算法

常见限流算法包括固定窗口、滑动窗口、令牌桶与漏桶;令牌桶允许突发,漏桶平滑输出,滑动窗口统计更平滑,选择取决于要抑制突发还是允许突发。

限流算法是什么

限流算法决定单位时间内放行多少请求。固定窗口实现最简单,但窗口边界处可能放行约两倍流量;滑动窗口统计更平滑,内存开销略高;令牌桶按速率补充令牌,允许突发;漏桶以恒定速率流出,擅长削峰填谷。选择取决于要抑制突发还是允许突发。

放在哪一层

限流要放在能全局计数的位置,否则按实例限流会在扩容后把整体阈值放大到实例数倍,扩容反而成了放大故障的手段。常见组合是网关做粗粒度全局限流,服务内做单实例自我保护,并在拒绝时返回明确的重试等待时间,让客户端能配合退避。

四种算法

算法特点适用场景
固定窗口实现简单,窗口边界可放行约两倍流量粗粒度保护
滑动窗口统计平滑,内存开销略高需要精确限流的接口
令牌桶按速率补令牌,允许突发API 配额与短时突发
漏桶恒定速率流出,削峰保护下游处理速率

基本信息

限流维度按用户、租户、接口或来源地址
拒绝语义返回明确的状态码与重试等待时间
全局与本地网关全局限流加服务本地保护
动态阈值随容量与下游健康度调整

典型使用场景

  • 开放 API 配额:按调用方限制单位时间请求量
  • 秒杀入口削峰:入口拦住超额流量,保护下游
  • 保护数据库:限制写入速率,避免连接数被打满
  • 租户隔离:防止单个租户占满共享资源
  • 防爬与防刷:按来源地址限制异常高频访问

阈值怎么定

阈值不能照搬压测的极限值,要留出安全余量,因为线上还叠加了重试流量、监控采集与批处理任务。常用做法是取单实例实测容量的一定比例作为保护线,再按下游最慢环节的承受能力确定全局限额。阈值还需要随实例规格与下游容量变化定期复核,扩容后忘记调整会让限流形同虚设。

限流要定义拒绝语义:返回明确状态码并携带重试等待时间,比静默排队或直接超时更有利于客户端配合与问题定位。

易错点

  • 固定窗口算法在窗口边界处放行双倍流量,峰值保护失效
  • 限流按实例维度实施,扩容后整体阈值随实例数放大
  • 只限流不限队列,超额请求直接失败,用户体验断崖式下降
  • 限流阈值照搬压测结果,未随实例规格与下游容量变化调整

数据来源与参考

  • 《System Design Interview》卷 1(Alex Xu)第 4 章
  • RFC 6585:429 Too Many Requests
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌