核心是让超额请求“有地方等、有节奏放”,而非单纯压低速率;需合理配比burst与rate,并依场景选delay(匀速延迟)、nodelay(瞬时放行)或默认排队,同时确保key精准、zone内存充足、日志可见。

用 limit_req 模块结合缓冲区平滑突发流量,核心不是压低速率,而是让超额请求“有地方等、有节奏放”,避免瞬间打垮后端或激怒用户。关键在 burst 与 rate 的配比,以及是否启用 delay 或 nodelay 来决定排队策略。
用 burst + 无 nodelay 实现可控排队释放
这是最常用、体验最稳的组合,适合列表页、详情页、搜索等非强实时接口:
-
配置示例:
limit_req zone=api burst=8;(隐式不加nodelay) - rate=5r/s 时,桶每 200ms 漏出 1 个令牌;burst=8 表示最多缓存 8 个超额请求
- 第 1–5 个请求按节奏立即/间隔处理;第 6–13 个进入 FIFO 队列,依次在 200ms、400ms…后被放行
- 第 14 个起直接返回 503(默认)或你设的 429
- 用户连点 8 次基本都能成功,第 9 次才提示“太频繁”,感知平滑
用 burst + delay 实现匀速延迟响应
适合对失败敏感但能接受轻微延迟的场景,比如头像加载、通知拉取:
-
配置示例:
limit_req zone=media burst=20 delay=10; - 前 10 个超限请求会被自动计算等待时间(如 100ms、300ms、600ms),并在响应头中带
X-RateLimit-Delay: 300 - 后 10 个仍按规则拒绝(503/429),不会无限堆积
- 效果是:P95 延迟上升但失败率归零,前端无须重试逻辑
- 注意 rate 要匹配后端平均耗时——若接口通常 150ms 返回,rate 可设为 6–7r/s
用 burst + nodelay 应对关键路径瞬时并发
适用于登录、下单、短信发送等“宁可失败也不愿卡住”的环节:
-
配置示例:
limit_req zone=auth burst=3 nodelay; - 前 3 个超限请求立刻通过(不排队),第 4 个开始严格按 rate 放行
- 本质是把 burst 当作“特批额度”,不是缓冲池;它提升的是尖峰头几下的吞吐,不改变长期速率
- 必须确保后端已压测验证能扛住这 3 笔并发,否则等于绕过保护
- 搭配
limit_req_status 429和前端Retry-After头,引导合理退避
让缓冲真正生效的三个硬性前提
光写 burst 不管用,下面三点缺一不可:
-
key 设计要准:别只用
$binary_remote_addr。NAT 环境下应叠加$http_user_agent;高危接口建议用$binary_remote_addr$uri隔离路径;已登录用户可用$http_x_user_id - zone 内存要足:1MB ≈ 存 1.6 万个 key。日活 IP 30 万?至少配 20MB。否则旧记录被挤掉,限流形同虚设
-
日志必须可见:在
log_format中加入$limit和$limit_key,并设limit_req_log_level warn;。否则被限了都不知道是谁、为什么被限

















