You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

秒级窗口滑动窗口请求限流算法理解与实现疑问

问题根源

你当前使用的是固定窗口加权近似的滑动窗口实现,存在精度缺陷:核心假设是「前一个窗口内的请求均匀分布」,但实际请求集中在前序窗口的末尾,导致加权计算结果完全失真。

你案例中请求#1发生在34.321,到请求#3的35.451已经间隔1.13秒,符合1秒间隔的要求,但你的算法默认前序34秒窗口有55%的请求落在当前滑动窗口范围内,误算出1.55 RPS的结果,本质是粗粒度整秒窗口的设计误差。


正确实现方案

方案1:精确滑动窗口(滑动日志)

适合阈值低、精度要求高的场景,实现逻辑最简单:

  • 存储所有最近1秒内的放行请求时间戳,不需要固定窗口计数
  • 新请求到达时,先删除所有早于 当前时间 - 1秒 的历史时间戳
  • 统计剩余时间戳的数量:
    • 数量小于阈值(此处为1):放行请求,将当前时间戳加入存储
    • 数量大于等于阈值:拒绝请求

你的案例计算逻辑:
请求#3到达时间为35.451,计算窗口左边界为34.451,34.321早于左边界被清除,剩余请求数为0,直接放行,完全符合预期。

方案2:分块滑动窗口(细粒度拆分)

适合高QPS场景,不需要存储全量请求,性能更高:

  • 将1秒的大窗口拆分为N个等大小的小窗口(通常拆分10~100个,比如10个100ms的小窗口,粒度越细精度越高)
  • 每个小窗口独立存储计数和窗口起始时间
  • 新请求到达时,先定位到当前所属的小窗口更新计数,再删除所有起始时间早于 当前时间 - 1秒 的小窗口
  • 统计剩余所有小窗口的计数总和:
    • 总和小于阈值:放行
    • 总和大于等于阈值:拒绝

你的案例如果拆分为10个100ms小窗口:
请求#1落在[34.300, 34.400)的小窗口,计数为1;请求#3到达时,所有早于34.451的小窗口都会被清除,[34.300, 34.400)窗口不在统计范围内,总计数为0,直接放行。


选型建议

如果你的业务限流阈值很低(比如1~100 QPS),直接用滑动日志实现即可,没有精度误差;如果是高QPS场景,拆分10个以上的小窗口即可满足绝大多数业务的精度要求。

内容的提问来源于stack exchange,提问作者hardhypochondria

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 12:21:00