Nginx 限制访问速度:limit_req 配置指南
恶意用户或自动化脚本高频请求网站,轻则拖慢体验,重则耗尽服务器资源。Nginx 的 limit_req 可以在代理层直接控制客户端的请求速率,把滥用流量挡在后端之前。这篇在 nginx:1.28 容器里用三组对照实验把 rate、burst、nodelay 三个参数的行为实测一遍——每种组合被拒绝多少、延迟多少,数据说话。
使用场景
三类典型需求:缓解 DDoS,限制单 IP 速率让攻击流量不再直接打穿后端;限制 API 用量,按客户端控制每秒请求数,保护后端不被滥用;保护登录注册入口,抑制暴力破解和批量注册脚本。
配置示例
1 | http { |
两个核心指令:limit_req_zone 定义规则——$binary_remote_addr 按客户端 IP 限流(二进制形式省内存),zone=mylimit:10m 划出 10MB 共享内存存限流状态,rate=1r/s 设定每客户端速率;limit_req 把规则应用到 location——burst=5 允许 5 个突发请求排队,nodelay 决定排队者是否立即处理。
实例一:burst + nodelay,快速放行前 N 个
实测配置 rate=3r/s、burst=5 nodelay,对同一 URL 快速连发 10 个请求(实测环境 nginx/1.28.3,下同):

结果 6 个 200、4 个 503:第 1 个请求消耗桶内初始配额,第 2~6 个占用 burst 的 5 个名额立即放行(nodelay 的含义),第 7 个起配额耗尽被拒。nodelay 模式适合”允许短突发、但总量硬上限”的接口——突发窗口内体验不受影响,超出就明牌拒绝。
实例二:不带 burst,严格限速
同样的速率,去掉 burst(limit_req zone=z3;)再连发 10 个:

1 个 200、9 个 503——没有 burst 缓冲,速率 3r/s 意味着两次请求间隔小于 333ms 的一律拒绝。这种形态只适合保护性极强的场景(如防暴力破解的登录接口);直接套在正常页面上,正常用户双击一下就会撞上 503。
实例三:burst 不带 nodelay,延迟排队
burst=5 但不写 nodelay,再连发 10 个,这次记录每个请求的耗时:

10 个全部 200,但注意每个请求的耗时。串行连发(实测):第 1 个 0.0008 秒立即处理,之后每个稳定多等约 0.33 秒——正好是 rate 的节奏(1/3 秒每请求)。再让 10 个请求同时到达,行为看得更清楚:1 个立即放行,5 个进队列后在 0.34 / 0.67 / 1.00 / 1.34 / 1.67 秒依次放行——排队上限就是 burst × (1/rate) ≈ 1.7 秒,剩余 4 个超出 burst 直接 503。这就是延迟模式的语义:超速的突发请求不被拒绝,而是排队匀速放行,代价是排队深度乘以间隔就是客户端要忍的最大延迟,适合异步任务回调、爬虫友好接口这类”不急”的流量。
三种模式对照着记:严格限速只放节奏内的请求,其余拒绝;nodelay 突发额度内立即放、超出拒;延迟模式突发额度内排队匀速放、超出拒。
错误写法对比:限流指令被”抢跑”
limit_req 生效在 access 阶段,如果 location 里用 return 直接返回内容,请求在更早的 rewrite 阶段就结束了,限流形同虚设——实测配置 limit_req + return 200 后连发 10 个请求,全部 200,零拒绝:

1 | # 错:return 在 rewrite 阶段抢跑,limit_req 从未执行 |
被限流拒掉的请求默认返回 503,语义上更适合用 429(Too Many Requests)告知客户端重试:limit_req_status 429; 一行即可。
注意事项
- rate 与 burst 要贴业务:限制过严误伤正常用户,过松失去保护;按真实流量分布(P95 请求间隔)反推参数,再灰度观察 503/429 比例。
- 多实例部署时限额会乘以实例数:limit_req 的计数在各实例内存里,4 台机器就是 4 倍速率;需要精确全局限流要上集中式方案(如 Redis 计数)。
- 限流键选对维度:
$binary_remote_addr按 IP,但移动出口 IP 聚集的场景(公司 NAT 后几百用户同 IP)会误伤,这类场景改按$http_authorization或业务 token 维度限。 - 缓存与限流的叠加顺序:如果同 location 还有 proxy_cache,缓存命中也会先过 limit_req 的计数,压测命中型流量时记得限流同样在消耗。
小结
回到开头的场景:把滥用流量挡在后端之前——limit_req 用两条指令就能做到,但三种模式的行为差异必须心里有数。实测结论浓缩成一句:严格限速是把杀器(超速即拒),burst+delay 是整形器(排队匀速),burst+nodelay 是缓冲带(额度内即放、超出即拒)。再配一条 limit_req_status 429 让拒绝语义正确,限流就算真正上线了。
本文由作者 2020-2024 年间的 CSDN 博客文章重构而来,原发布于 CSDN。