nginx限速需先在http块定义limit_req_zone共享内存区,再在精确匹配的location中启用limit_req;必须用$binary_remote_addr、避免if内使用、合理设置burst与rate,并建议配合limit_conn和自定义429响应。

直接在 nginx.conf 里用 limit_req 限速,核心是两步:先定义限速区域(http 块),再在具体位置启用(server 或 location 块)。关键不是“能不能加”,而是“加在哪、怎么配才真正生效”。
限速区域必须定义在 http 块中
这是共享内存区,所有 worker 进程共用。漏掉这步,limit_req 指令会报错。
示例(限制单 IP 每分钟最多 5 次请求):
http {
limit_req_zone $binary_remote_addr zone=login_rate:5m rate=5r/m;
}
-
$binary_remote_addr:推荐用这个,比$remote_addr更省内存,且能穿透代理(配合real_ip模块时更准) -
zone=login_rate:5m:起个名字叫login_rate,分配 5MB 内存存计数器 -
rate=5r/m:每分钟 5 个请求,适合登录类接口;也可写1r/s,但r/m对防爆破更友好
在 location 中精准启用限速
别写宽泛的 location /api/,要精确匹配目标路径,比如登录接口:
location = /api/v1/login {
limit_req zone=login_rate burst=3 nodelay;
limit_req_status 429;
proxy_pass http://backend;
}
-
=表示严格匹配,避免误伤/api/v1/login-xxx -
burst=3:允许用户手抖多点几次,但绝不放行持续高频请求 -
nodelay:突发请求不排队,立即返回 429 或放行——防止攻击者靠“占队列”耗尽资源 -
limit_req_status 429:返回标准 HTTP 状态码,语义清晰,不暴露后端细节
防止常见失效写法
- ❌ 别用
$remote_addr:反向代理环境下它常是负载均衡 IP,导致全站被限 - ❌ 别把
limit_req放在if里:Nginx 不支持,配置会静默失效 - ❌ 别设
burst=100配rate=1r/s:等于每 100 秒集中打 100 次,正中暴力破解下怀 - ❌ 别忽略白名单:内网运维、监控探针需豁免,可用
geo+map实现动态绕过
可选但强烈建议的增强项
- 加
limit_conn控制并发连接数(防多线程绕过):limit_conn_zone $binary_remote_addr zone=login_conn:5m; limit_conn login_conn 3; # 每 IP 最多 3 个并发连接
- 自定义 429 响应体,隐藏技术栈:
error_page 429 @rate_limited; location @rate_limited { return 429 '{"code":429,"msg":"Too many requests"}'; add_header Content-Type "application/json"; }
不复杂但容易忽略











