limit_req 高并发限流需令牌桶算法、精准key设计、burst/nodelay协同三者缺一不可;key决定限流维度与隔离效果,burst控制缓冲深度,nodelay影响突发处理方式,分层策略与可观测机制保障业务适配与稳定性。

limit_req 不是“开个开关就高并发限流”,它靠的是令牌桶算法 + 精准的 key 设计 + burst/nodelay 协同调度,三者缺一不可。真正扛住高并发,关键不在参数堆叠,而在是否贴合业务流量的真实节奏和隔离需求。
选对限流维度:key 决定谁被限、谁和谁互不干扰
同一个限流 zone 里,所有请求共用一套令牌桶。key 设计错了,限流就失效甚至误伤:
- 按 $binary_remote_addr 限:适合防简单爬虫或 CC,但企业内网/NAT 下多个用户共享 IP,容易集体受限;
- 按用户身份限:从 Header(如 X-User-ID)或 Cookie 提取 user_id,再用 map 指令过滤空值,避免未登录用户占用额度;
- 按接口路径+参数组合限:比如对 /api/v1/order/create 单独设 zone,或用正则提取商品 ID($request_uri ~* /item/(\d+)),实现热点隔离,防止一个爆款商品拖垮整个订单服务。
注意:key 越细,内存占用越高。10MB zone 最多存约 16 万个唯一 key,超出后触发 LRU 淘汰,老用户可能突然被限——这不是 bug,是设计权衡。
burst 和 nodelay 配合:让突发流量既可控又可响应
rate 是平均速率,burst 是缓冲深度,nodelay 决定怎么处理缓冲区里的请求:
- 不加 nodelay:超速请求排队,按 rate 节奏逐个放行,后端压力平稳,但用户感知延迟升高;
- 加 nodelay:只要桶里还有令牌(哪怕只剩 1 个),排队请求立刻处理,秒级响应,但瞬时压到后端;
- 典型搭配:支付回调用 burst=5 nodelay(保低延迟),商品详情页用 burst=30 不加 nodelay(换后端稳定)。
分层挂载策略:不同场景用不同限流强度
全局限流一刀切,会卡住正常流量。要用 location + if + map 实现动态分层:
- 登录用户放宽:limit_req zone=user_limit burst=100 nodelay;;未登录用户收紧:limit_req zone=guest_limit burst=5;
- 秒杀活动动态提速:用 map 根据 query 参数切换 rate,例如 map $arg_activity_id $req_rate { default 1r/s; "seckill2026" 100r/s; },再绑定 rate=$req_rate;
- 跳过健康检查:用 if 判断 User-Agent,匹配 Prometheus 或 HealthCheck 时清空 limit_key,避免探针被限。
可观测与兜底:限流不是拒绝就完事
限流生效后必须能追踪、能告警、能降级:
- 在 log_format 中加入 $limit_rate 和 $limit_burst,记录哪些请求被延时或拒绝;
- 配合 error_page 指令,把 503 响应重写为统一 JSON 格式(如 {"code":429,"msg":"rate limited"}),前端友好;
- 当持续大量 503 出现时,触发熔断逻辑(如通过 upstream health_check 或外部监控联动降级路由)。











