不加nodelay仅用burst可实现柔性整形:请求超速时排队等待、匀速释放,避免突刺冲击;加nodelay则立即放行burst内请求或直接503,丧失平滑性。

nginx 的 limit_req 指令本身没有 delay 参数,但你提到的“delay”实际是指 burst 配合 nodelay 的行为差异——真正实现“柔性整形”(即平滑限速、允许短暂突发并延迟处理)的关键,是**不加 nodelay,仅用 burst**。
理解 burst 与 nodelay 的本质区别
当配置如 limit_req zone=foo burst=10; 时:
- nginx 会维护一个“令牌桶”,按设定速率(如 5r/s)匀速填充;
- 每个请求消耗一个令牌;
- 若无令牌可用,但未超
burst容量,则请求被**排队缓存**,等待下一个令牌生成后再处理——这就是“延迟执行”,体现为响应时间变长,而非直接拒绝; - 只有排队长度超过
burst(即缓冲区满),后续请求才返回 503。
如何配置出真正柔性的速率整形
示例:限制平均 3r/s,允许最多 6 个请求暂存排队,不丢弃、不立即拒绝:
limit_req_zone $binary_remote_addr zone=api:10m rate=3r/s;
server {
location /api/ {
limit_req zone=api burst=6;
proxy_pass http://backend;
}
}
此时效果是:
- 平稳流量下,请求几乎零延迟通过;
- 突发 8 个请求到达:前 6 个进队列,第 7、8 个被 503 拒绝;
- 队列中请求按每 333ms(1/3 秒)释放一个,实现自动“拉平”输出节奏。
避免常见误用:nodelay 不等于柔性,而是激进限速
如果写成 limit_req zone=api burst=6 nodelay;:
- 所有在
burst内的请求(最多 6 个)**立刻放行**,不排队、不延迟; - 第 7 个起直接 503;
- 这其实是“突刺式放行 + 突然拦截”,毫无柔性可言,反而可能压垮后端。
配合其他指令提升稳定性
柔性整形需搭配合理超时与降级策略:
- 设置
proxy_read_timeout 60;,防止后端慢导致排队请求无限等待; - 用
limit_req_status 429;统一返回 429 Too Many Requests,便于客户端识别限流; - 对关键接口,可叠加
limit_conn控制并发连接数,防连接耗尽。










