Nginx 通过 limit_req_zone 和 limit_req 指令配合 geo 模块实现对特定 IP 的请求量限制:先用 geo 定义目标 IP 的 $limit_key 变量,再以该变量为 key 创建限流区域,仅匹配 IP 触发限流;burst 和 nodelay 参数控制突发请求处理方式;可通过响应头、错误日志及 curl 测试验证效果。

在 Nginx 中限制特定 IP 在指定时间内的总请求量,主要依靠 limit_req_zone 和 limit_req 指令配合使用,并结合 geo 或 map 模块实现“仅对特定 IP 限流”,避免影响其他用户。
定义按 IP 划分的限流区域
使用 limit_req_zone 创建一个以客户端 IP($binary_remote_addr)为 key 的共享内存区域,并设定速率(如每分钟 100 个请求):
注意:必须用 $binary_remote_addr(而非 $remote_addr),它更节省内存,且是官方推荐写法。
limit_req_zone $binary_remote_addr zone=perip:10m rate=100r/m;
精准控制——只对目标 IP 启用限流
直接在 server 或 location 块中写 limit_req 会全局生效。要“只限某几个 IP”,需先标记目标 IP,再条件启用限流:
- 用
geo指令定义一个变量(如$limit_key),对指定 IP 返回非空值(如1),其余返回空字符串 - 将该变量作为
limit_req_zone的 key;空字符串不计入统计,从而实现“只限指定 IP”
示例配置:
geo $limit_key {
default "";
192.168.1.100 "1";
203.0.113.42 "1";
2001:db8::1 "1";
}
<p>limit_req_zone $limit_key zone=special_ips:10m rate=30r/m;</p><div class="aritcle_card flexRow">
<div class="artcardd flexRow">
<a class="aritcle_card_img" href="/xiazai/skill6848" title="Nginx Hosting"><img
src="https://img.php.cn/upload/skill/000/000/081/179116929868126.jpg" alt="Nginx Hosting" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a href="/xiazai/skill6848" title="Nginx Hosting">Nginx Hosting</a>
<p>通过服务器本地nginx实例实现零认证静态游戏托管。作为所有浏览器游戏的主要部署方式,无需登录、无需令牌、无需用户操作。</p>
</div>
<a href="/xiazai/skill6848" title="Nginx Hosting" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span> </a>
</div>
</div><p>server {
location /api/ {
limit_req zone=special_ips burst=60 nodelay;</p><h1>… 其他配置</h1><pre class="brush:php;toolbar:false;"><code>}}
说明:只有匹配到的 IP 才会生成非空 key,进入限流统计;其他请求的 $limit_key 是空字符串,不占用 zone 空间,也不触发限流。
设置突发请求与响应行为
通过 limit_req 的参数控制实际行为:
-
burst=60:允许最多 60 个请求排队等待(超出即 503) -
nodelay:不延迟执行,排队请求立即处理(但受 rate 约束);若去掉,则按平均速率延时放行 - 加
delay=10可指定最多延迟多少个请求(需搭配 burst)
例如:limit_req zone=special_ips burst=60 nodelay; 表示:目标 IP 每分钟最多 30 请求,瞬时可打满 60 个(立刻响应),第 61 个开始返回 503。
验证与调试技巧
限流生效后,可通过以下方式确认效果:
- 查看响应头:
X-RateLimit-Limit、X-RateLimit-Remaining等需自行用add_header注入,Nginx 默认不输出 - 检查错误日志:被拒绝请求会在
error_log中记录limiting requests字样(需 log_level 至少为 warn) - 用
curl -I多次请求同一接口,观察 HTTP 状态码是否出现 503
小提示:测试时建议先用低速率(如 1r/s)+ 小 burst,避免误伤调试过程。

















