nginx 中限流由 limit_req 指令实现,需在 http 块中定义 limit_req_zone,再在 location 中引用;location 仅选择应用规则的请求路径,不配置限流逻辑本身。

在 Nginx 中,location 块本身不直接支持访问频次控制,真正实现限流的是 limit_req 指令,它需配合 limit_req_zone 在 http 或 server 级别定义,再在特定 location 中引用。location 的作用是“选择哪些请求应用该限流规则”,而非配置限流逻辑本身。
定义限流区域(必须在 http 块中)
限流依据(如 IP、用户标识)和速率参数需提前声明,不能写在 location 内:
- 常用按客户端 IP 限流:
limit_req_zone $binary_remote_addr zone=ip_limit:10m rate=5r/s;
其中$binary_remote_addr更节省内存,10m是共享内存大小,5r/s表示每秒最多 5 个请求 - 若需按 URL 参数或 header 限流(如 API key),可改用变量:
limit_req_zone $arg_apikey zone=api_limit:10m rate=10r/m;(每分钟 10 次)
在 location 中启用限流规则
把已定义的 zone 绑定到具体路径,支持多种行为控制:
- 基础应用:
location /api/ { limit_req zone=ip_limit; } - 允许突发请求(burst)并排队等待:
limit_req zone=ip_limit burst=10 nodelay;
表示最多缓存 10 个待处理请求;加nodelay则不延迟立即响应(可能返回 503),不加则平滑排队 - 对静态资源等无需限流的路径,可单独关闭:
location ~* \.(jpg|png|css|js)$ { limit_req off; }
常见组合与注意事项
实际部署时需注意作用域继承与冲突:
- 多个 limit_req 指令在同一 location 中,只有最后一个生效;如需多维度限流(IP + 接口),需用不同 zone 并分别调用
- 如果 server 块已设
limit_req,location 中未覆盖,则继承;显式写limit_req off可禁用继承 - 测试时可用 curl 配合 sleep 观察效果:
for i in {1..10}; do curl -sI http://localhost/api/test | head -1; sleep 0.2; done
验证与调试技巧
限流是否生效可通过响应头和日志确认:
- 开启
limit_req_log_level warn;(默认 error),在 error.log 中看到limiting requests表示触发限流 - 添加
limit_req_status 429;将超限响应码改为标准的 429 Too Many Requests - 配合
log_format记录 $limit_rate 变量,可输出当前匹配的限流 zone 名称用于排查











