nginx限流需在http块定义limit_req_zone,location中用burst+nodelay实现平滑漏桶控制:按ip或uri设zone与rate,配合429状态码和warn日志提升可观测性。

直接在 location 块里写 limit_req 不会生效,必须配合 http 块中预先定义的 limit_req_zone。平滑限流的关键不是“拦住多少”,而是让突发流量被缓冲、不卡顿、不打爆后端——靠 burst + nodelay 组合实现漏桶的柔性控制。
第一步:在 http 块定义漏桶规则
所有限流状态都依赖共享内存,必须放在 http 级别,不能嵌套在 server 或 location 里:
-
选对 key:常用
$binary_remote_addr(按客户端 IP 限流,内存更省);若需按接口路径区分,可用$uri(忽略查询参数)或$request_uri(含完整 URL) -
设好 zone:如
zone=api_submit:10m表示开一块 10MB 内存,约存 16 万个独立计数状态 -
定准 rate:如
rate=5r/s表示每秒最多“漏出”5 个请求,即平均 200ms 放行一个
示例:
http {limit_req_zone $binary_remote_addr zone=api_submit:10m rate=5r/s;
limit_req_zone $uri zone=api_order:10m rate=10r/m;
}
第二步:在 location 中精准启用并调平滑参数
只对目标接口生效,推荐用 location = /path 精确匹配,避免前缀匹配误伤:
-
必须指定 zone 名称:如
limit_req zone=api_submit; -
加 burst 缓冲突发:如
burst=20开一个容量为 20 的 FIFO 队列,把暂时无法立刻漏出的请求暂存 -
加 nodelay 实现“即入即走”:队列里的请求不排队等待,只要没超
burst就立刻交给后端处理,整体节奏仍受rate控制
示例:
location = /api/v1/submit {limit_req zone=api_submit burst=20 nodelay;
proxy_pass http://backend;
}
第三步:提升可用性与可观测性
默认行为对运维和前端都不友好,建议补充:
-
返回标准限流码:加
limit_req_status 429;,让前端能明确识别“被限流”,而不是收到 503 -
降低日志级别:加
limit_req_log_level warn;,避免大量限流事件刷屏 error 日志 -
按业务身份限流(可选):如已登录用户,可用
$cookie_uid或$http_x_user_id替代 IP 作为 key,更精准
第四步:验证是否真正平滑
用简单压测看效果,重点观察响应时间和失败率:
- 并发 10 个请求打同一接口:应全部成功,响应时间集中在 0–200ms 区间
- 并发 30 个请求:前 25 个(5 + burst=20)大概率成功,第 26 起开始返回 429
- 持续每秒发 6 个请求:长期运行后,约 1/6 的请求触发 429,符合 5r/s 设定
注意:漏桶控制的是平均速率,短时小幅超发是允许的,这正是它比固定窗口计数更自然、更抗抖动的原因。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











