Nginx限制单IP并发连接需先在http块定义limit_conn_zone,再在server块用limit_conn启用;必须配合使用才生效,且需注意代理场景下的真实IP识别与内存配置。

在 Nginx 虚拟主机(server 块)中限制单个客户端 IP 的最大并发连接数,核心是两步配合:先在 http 块定义共享内存计数区,再在目标 server 或 location 中启用限制指令。单独写 limit_conn 不生效,必须有对应的 limit_conn_zone 支撑。
1. 在 http 块顶部定义 IP 连接计数区域
这一步必须放在所有 server 块之前,且只能出现在 http{} 上下文中:
- 使用
$binary_remote_addr作为 key:比$remote_addr更省内存(IPv4 固定 4 字节),且不受请求头伪造影响; - 推荐写法:limit_conn_zone $binary_remote_addr zone=perip:10m;
-
perip是自定义 zone 名,需全局唯一;10m内存约支持 16 万~32 万个独立 IP,若用户量大可升至20m; - 若 Nginx 前有 CDN、SLB 或 WAF,需改用
$realip_remote_addr并配置set_real_ip_from和real_ip_header,否则所有请求会被识别为代理 IP。
2. 在 server 块中启用单 IP 连接限制
把限制直接加在你要防护的虚拟主机配置内,例如:
-
limit_conn perip 5; —— 表示该
server下每个真实 IP 最多维持 5 个活跃 TCP 连接; - 它统计的是已读取完请求头、尚未关闭的连接(含 keepalive、HTTP/2 多路复用中的底层连接),不是请求数;
- 若同时在
location /api/里写了limit_conn perip 3,则该路径以更严格的 3 为准; - 不建议全站统一设为 1,否则正常浏览器多标签页易触发限流。
3. 提升可用性与可观测性(推荐补充)
让限流行为更清晰、问题更容易排查:
-
limit_conn_status 429; —— 返回
429 Too Many Requests,语义比默认503更明确; - limit_conn_log_level error; —— 只在真正超限时记录 error 级日志,避免刷屏;
- 可叠加
limit_rate 200k;对已放行的连接限速,防止单连接持续占带宽; - 搭配
keepalive_timeout 15;及时释放空闲长连接,避免无效占用配额。
4. 验证是否生效
不要依赖响应状态码肉眼判断,直接查 Nginx 错误日志:
- 触发限流时,
error.log会出现类似limiting connections by zone "perip"的 warn 或 error 记录; - 用压测工具如
hey -c 20 -n 100 http://your-domain.com/,观察日志中限流条目是否随并发增长而增加; - 注意:若日志出现
limit_conn: cannot add connection,说明共享内存不足,需增大 zone size。











