Nginx虚拟主机连接数限制需先在http块定义limit_conn_zone共享内存区,再在server或location块用limit_conn引用该zone;须配合real_ip配置识别真实IP,并可结合limit_req实现双层限流。

在 Virtual Host(即 server 块)中配置连接数限制,核心是用 limit_conn 指令绑定已在 http 块定义好的共享内存区域。它不直接写“每 IP 最多 X 连接”,而是引用预设的 zone,靠 Nginx 内部状态计数实现拦截。
必须先在 http 块定义共享内存区
这一行不能放在 server 或 location 里,否则会启动失败:
limit_conn_zone $binary_remote_addr zone=perip:10m;-
$binary_remote_addr是紧凑二进制格式 IP,比$remote_addr节省内存; -
zone=perip:10m表示创建名为perip的共享内存区,10MB 约支持 16 万个独立 IP 的并发状态记录。
在 server 块中启用单 IP 连接限制
把规则加到目标 virtual host 的 server 块内,作用范围覆盖该站点所有请求:
-
limit_conn perip 5;—— 每个 IP 最多维持 5 个活跃 TCP 连接; -
limit_conn_log_level error;—— 超限时记为 error 级日志,方便 grep 定位攻击源; -
limit_conn_status 503;—— 返回 503(也可设为 429,语义更明确); - 若只想限制特定路径(如
/api),可把这三行移到对应location块内。
真实 IP 识别必须同步处理
如果 Nginx 前面有 CDN、WAF 或负载均衡,$binary_remote_addr 默认拿到的是代理 IP。需补全以下配置:
-
set_real_ip_from 192.168.0.0/16;—— 列出可信代理网段; -
real_ip_header X-Forwarded-For;或X-Real-IP(按上游实际传递的头字段选); - 否则限流对象会错,可能把整个 CDN 的流量算成一个 IP。
配合 keepalive 和 limit_req 提升实效性
limit_conn 防的是连接耗尽,但单独用容易被“少量长连接 + 高频请求”绕过:
-
keepalive_timeout 15;—— 避免合法用户长连接长期占用额度; -
limit_req zone=perip burst=10 nodelay;—— 在同一 zone 上叠加请求速率控制,形成连接层 + 请求层双控; - 注意:两个模块共用 zone 名(如
perip)时,Nginx 会复用内存区,无需重复定义。


















