Nginx的limit_req模块基于漏桶算法限制请求频率,通过limit_req_zone定义共享内存区(如zone=ip_limit:10m rate=5r/s),再在location中用limit_req指令启用(如burst=10 nodelay),配合日志变量$limit_status监控限流状态。

Nginx 的 limit_req 模块用于限制客户端对某个 location 或 server 的请求处理频率,防止突发流量冲击后端服务。核心是通过“漏桶算法”控制单位时间内的请求数,配合共享内存区(zone)实现跨 worker 进程的计数。
定义限流区域(zone)
在 http 块中使用 limit_req_zone 指令定义一个共享内存区域,指定键、大小和速率:
http {
limit_req_zone $binary_remote_addr zone=ip_limit:10m rate=5r/s;
}说明:
-
$binary_remote_addr:以客户端 IP 的二进制形式作为键,节省内存;比$remote_addr更高效 -
zone=ip_limit:10m:声明名为ip_limit的共享内存区,大小为 10MB(可支撑约 16 万个 IP 的状态) -
rate=5r/s:允许平均 5 个请求/秒(也支持30r/m表示每分钟 30 次)
在 location 中启用限流
在需要保护的 location 或 server 块中添加 limit_req 指令:
server {
location /api/ {
limit_req zone=ip_limit burst=10 nodelay;
proxy_pass http://backend;
}
}关键参数说明:
-
zone=ip_limit:引用前面定义的限流区域 -
burst=10:设置“突发容量”,即漏桶的缓冲队列长度,允许最多 10 个请求排队等待(默认为 0) -
nodelay:不延迟执行排队请求,而是立即拒绝超出burst的请求(返回 503);若省略,则按速率平滑释放排队请求(可能造成延迟)
常用组合与行为差异
不同参数组合影响用户体验和防护强度:
-
limit_req zone=ip_limit;:等价于burst=0 nodelay,严格限速,超速直接 503 -
limit_req zone=ip_limit burst=20;:允许最多 20 个请求积压,后续请求按 5r/s 匀速处理,有延迟但不丢弃 -
limit_req zone=ip_limit burst=20 nodelay;:允许瞬间打满 20 个请求,第 21 个就立刻 503,适合防刷但容忍短时高峰
配合日志与状态监控
可通过日志观察限流效果,在 http 块中定义日志格式并记录限流状态:
log_format limitlog '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" $request_time '
'limit_status:$limit_status';
<p>server {
access_log /var/log/nginx/limit_access.log limitlog;
location /api/ {
limit_req zone=ip_limit burst=5 nodelay;
...
}
}$limit_status 变量值为 passed、delayed、rejected 或 delayed_dry_run,便于分析拦截原因。
配置完成后记得 nginx -t 测试语法,并 nginx -s reload 生效。注意:burst 值不宜过大,否则失去限流意义;zone 内存大小需根据并发 IP 数预估,避免溢出导致限流失效。


















