四种经典的限流算法,每种都有适用的场景。从原理到代码实现,一文讲透。

一、为什么要限流

  • 1.1 保护系统——防止流量超过处理能力
  • 1.2 公平性——防止个别用户占用过多资源
  • 1.3 成本控制——第三方 API 调用次数限制

二、固定窗口算法

  • 2.1 原理——在一个固定时间窗口内计数,超过阈值则拒绝
  • 2.2 代码实现——AtomicLong + 定时重置
  • 2.3 临界问题——窗口切换时的”突刺”
  • 2.4 优点——实现简单
  • 2.5 缺点——不够平滑

三、滑动窗口算法

  • 3.1 原理——将窗口细分为多个小窗口,随时间滑动
  • 3.2 代码实现——环形数组 + 时间戳
  • 3.3 Sentinel 的 LeapArray 实现
  • 3.4 优点——解决了临界问题
  • 3.5 缺点——存储开销稍大

四、漏桶算法

  • 4.1 原理——请求先进入”桶”,以固定速率流出
  • 4.2 代码实现——ScheduledThreadPoolExecutor
  • 4.3 优点——流量整形,平滑输出
  • 4.4 缺点——无法处理突发流量

五、令牌桶算法

  • 5.1 原理——以固定速率产生令牌,请求需要获取令牌
  • 5.2 代码实现——Guava RateLimiter
  • 5.3 预热模式——RateLimiter.create(permitsPerSecond, warmupPeriod, unit)
  • 5.4 优点——允许一定的突发流量

六、四种算法对比

  • 6.1 适用场景——突发 vs 平滑
  • 6.2 分布式限流——Redis + Lua 实现
  • 6.3 选择决策树

七、总结

  • 固定窗口/滑动窗口——适合 QPS 限制
  • 漏桶/令牌桶——适合流量整形
  • Sentinel/Guava RateLimiter 已经实现了这些算法