直接在limit_req中加burst=n启用突发缓冲,核心是为超速请求提供排队空间而非提升速率;需先在http块用$binary_remote_addr定义zone,再于location中配置burst及可选nodelay/delay参数,burst值应据接口qps和压测结果设定并配合日志监控调优。

直接在 limit_req 指令中加上 burst=N 就能启用突发缓冲,关键不是“放行多少”,而是给超出速率的请求一个可排队的空间,避免瞬间打挂后端或大量返回 503。
先定义好限流区域(zone)
必须在 http 块里声明共享内存区,这是 burst 起作用的前提:
- 推荐用
$binary_remote_addr作 key,省内存、查询快;代理环境下要换成可信的$http_x_forwarded_for并配set_real_ip_from - rate 值按接口日常 QPS 设,比如读接口平均 50 QPS,rate 可设为
60r/s - 内存大小留足:
zone=api:10m约支持 16 万个 IP 的状态记录
在 location 中启用 burst 缓冲
只对需要保护的路径生效,比如 /api/order 或 /login:
-
limit_req zone=api burst=30;:允许最多 30 个请求进队列排队,按 rate 匀速放出 -
limit_req zone=api burst=30 nodelay;:只要没超 burst,超限请求立刻通过,不排队(适合下单、登录等强实时场景) -
limit_req zone=api burst=30 delay=15;:前 15 个超限请求被匀速延迟放行,响应头带X-RateLimit-Delay,后 15 个直接拒
burst 值怎么设才合适
不能拍脑袋填,得结合业务特征和压测结果:
- 读接口(如商品详情):burst 可设为日常 QPS 的 2~3 倍,比如 QPS=50,burst=100~150,相当于容纳 2 秒左右突发
- 写接口(如下单):慎用纯排队,优先选
burst + nodelay,但必须确认后端压测过对应并发量(比如 burst=30 就意味可能同时涌来 30 笔下单) - 健康检查或静态资源:建议
burst=0,避免干扰监控或缓存命中 - burst 过大(如 1000)+ nodelay ≈ 实际没限流,只是把失败延后到内存耗尽
让 burst 行为看得见、调得准
配完不看日志等于白配:
- 加日志变量:
log_format main '$remote_addr - $limit_key $limit_rate $limit_req_status';,能看清哪个 IP 或用户触发了限流 - 调高日志级别:
limit_req_log_level warn;,记录所有排队/拒绝动作,不只是 error - 监控指标:重点关注
nginx_http_limit_req_delayed_total和rejected_total,上升明显说明 burst 偏小或 rate 偏低 - 压测验证:用
wrk -c 50 -d 10 http://your-api/观察响应时间是否呈固定间隔(如 100ms、200ms…),确认漏桶节奏生效











