nginx的limit_req模块本质是漏桶算法的工程实现,以毫秒为单位离散判断请求放行(如rate=10r/s即每100ms最多放行1个);burst参数提供临时缓冲区,允许短时请求堆积排队按固定间隔漏出;nodelay使burst变为瞬时配额,提升突发响应能力但不改变长期速率;key设计需匹配业务粒度,zone内存须充足以防限流失效;建议结合limit_conn及业务层限流构建多级防护体系。

nginx 的 limit_req 模块本质是漏桶算法的工程实现,但它的“漏”不是连续匀速滴水,而是以毫秒为单位做离散判断——比如 rate=10r/s 实际等价于“每 100 毫秒最多放行 1 个请求”。这个细节直接决定它在突发流量下的表现:不加调优时,哪怕只比前一个请求早 1 毫秒到达,也会被拒绝。
burst 参数:给漏桶加个临时缓冲区
burst 的作用不是提高平均速率,而是允许短时请求堆积。它定义的是“桶能多装多少个请求”,这些请求不会立刻被处理,而是排队等待按固定间隔漏出。
- 设
rate=5r/s(即每 200ms 一个),burst=4,意味着桶最多存 4 个待处理请求 - 若 1 秒内来了 8 个请求:前 5 个中,第 1 个立即处理,第 2–5 个分别在 200ms、400ms、600ms、800ms 后被放行;后 3 个因桶满被拒
- burst 值越大,缓冲能力越强,但会拉长尾延迟——第 4 个排队请求要等 600ms 才开始处理
nodelay:跳过排队,把 burst 当作“瞬时配额”用
加上 nodelay 后,burst 不再是排队缓冲,而是允许立即放行的额外额度。它让漏桶行为更接近令牌桶的突发适应性。
- 同样
rate=5r/s、burst=4、nodelay:1 秒内前 5 个请求全部立即通过(第 1 个按规则,后 4 个走 burst 额度) - 第 6 个请求开始,恢复严格按 200ms 间隔放行;如果第 6 个在第 1 个之后 100ms 就到,会被拒绝
- nodelay 不改变长期速率,只缓解“尖峰头几下”,适合登录、下单等需快速响应的关键路径
key 设计与共享内存:别让限流失效
限流效果取决于 limit_req_zone 中 key 的粒度是否匹配业务意图。key 太粗会误伤,太细则失去保护意义。
- 用
$binary_remote_addr是最常见做法,但要注意:NAT 环境下多个用户共用一个公网 IP,容易集体受限 - 对登录接口,可组合
$binary_remote_addr$http_user_agent区分设备类型,避免手机端刷新影响桌面端 - zone 内存大小必须足够:1MB 约存 1.6 万个 IP 计数,若业务有 50 万活跃 IP,zone 至少配 32MB,否则旧记录被挤出导致限流失效
多级限流协同:单靠漏桶不够
纯漏桶对长周期洪峰乏力,建议分层应对:
- 接入层用
limit_req控制单 IP 请求节奏(防爬、防刷) - 配合
limit_conn限制单 IP 并发连接数(防慢连接攻击) - 核心接口前置 Redis 计数器,按用户 ID 或订单号做业务维度限流(如“每人每天最多提交 3 次支付”)
- 所有限流都配置
limit_req_status 429和详细日志,便于后续分析真实瓶颈点











