nginx 中 limit_req 限流需先用 limit_req_zone 定义共享内存区域(如 zone=perip:10m rate=5r/s),再在 location 中通过 limit_req 应用,支持 burst 和 nodelay 控制突发流量,并可通过 map 实现条件限流与日志调试验证。

在 Nginx 中使用 limit_req 限制请求频率,核心是配合 limit_req_zone 指令定义限流规则,再通过 limit_req 应用到具体 location 或 server 块中。配置生效需注意作用域、键值选择和突发处理策略。
定义限流区域(limit_req_zone)
限流必须先声明一个共享内存区域,用于统计和追踪客户端请求。常用键是 $binary_remote_addr(压缩后的 IP 地址),兼顾精度与内存效率。
- 语法示例:
limit_req_zone $binary_remote_addr zone=perip:10m rate=5r/s; -
zone=perip:10m表示创建名为perip、大小为 10MB 的共享内存区(约可存储 16 万个 IP) -
rate=5r/s表示每秒最多允许 5 个请求;也支持rate=30r/m(每分钟 30 次) - 键值也可用
$host、$request_uri或组合如$binary_remote_addr$uri实现更细粒度控制
在 location 中启用限流(limit_req)
将定义好的 zone 绑定到具体路径,决定如何执行限流策略。
- 基础用法:
limit_req zone=perip;—— 超出速率即返回 503 - 允许少量突发:
limit_req zone=perip burst=10 nodelay;
其中burst=10表示允许最多积压 10 个请求,nodelay让这 10 个请求立即通过(不排队),适合应对短时流量尖峰 - 若不用
nodelay,Nginx 会以设定速率匀速释放 burst 队列中的请求,可能造成延迟累积
全局或条件性限流配置技巧
限流可按需嵌套或排除特定请求,避免误伤正常行为。
- 放在
http块中实现全局默认限流;放在server或location中则局部生效 - 配合
if不推荐(Nginx 官方不建议在 limit_req 前加 if),可用map提前判断:map $request_uri $limit_key { default $binary_remote_addr; ~^/api/v1/health$ ""; }
再在 zone 中用$limit_key,空字符串表示跳过限流 - 对静态资源(如 .js/.css/.png)通常无需限流,可单独配置不启用
limit_req
验证与调试限流是否生效
配置后 reload Nginx(nginx -s reload),再通过日志和响应状态确认效果。
- 开启限流日志:
limit_req_log_level warn;(默认 error 级别,warn 可记录被限请求) - 配合
log_format记录 $status 和 $limit_rate 变量,便于区分 503 是限流还是其他错误 - 用
ab -n 100 -c 20 http://your-site/或wrk -t2 -c10 -d5s http://your-site/模拟并发,观察返回状态码分布 - 检查共享内存使用:
nginx -T 2>/dev/null | grep limit_req_zone确认 zone 名称和参数无拼写错误











