nginx通过limit_conn模块限制单ip并发tcp连接数,需在http块定义共享内存区(如limit_conn_zone $binary_remote_addr zone=perip:10m),再在server或location中启用limit_conn perip 5;代理环境下需配合realip模块识别真实ip,并建议搭配limit_req和keepalive_timeout优化限流效果。

直接限制单个 IP 的并发连接数,不是限制请求数,而是控制已建立、尚未关闭的 TCP 连接数量。Nginx 用 limit_conn 模块实现,核心是两步:定义共享内存区域记录连接状态,再在具体位置启用限制规则。
必须在 http 块定义共享内存区
这一步缺了,后续所有配置都不生效:
- 写在
http{}最外层,不能放在server或location里,否则启动报错 - 推荐用
$binary_remote_addr作 key,比$remote_addr更省内存(IPv4 固定 4 字节,IPv6 固定 16 字节) -
zone=perip:10m表示分配 10MB 共享内存,约支持 16 万独立 IP;用户量大可设为20m - 示例:
limit_conn_zone $binary_remote_addr zone=perip:10m;
在 server 或 location 中启用限制
引用上面定义的 zone 名,并设定每个 IP 允许的最大并发连接数:
- 写在
server{}块中,对整个站点生效;写在location /api/中,只限制该路径 -
limit_conn perip 5;表示每个 IP 最多维持 5 个活跃 TCP 连接(含 keepalive、HTTP/2 多路复用流) - 若多个作用域都配置了 limit_conn,以数值更小的那个为准
- 值不宜设为 1(浏览器多标签页易触发),常见合理范围是 3~10;爬虫防护可设为 3
代理环境下要识别真实客户端 IP
如果 Nginx 前有 CDN、SLB 或 WAF,$binary_remote_addr 默认是代理地址,需配合 realip 模块:
- 确认已加载
http_realip_module(编译默认包含) - 配置可信上游网段:
set_real_ip_from 10.0.0.0/8;、set_real_ip_from 192.168.0.0/16; - 指定头字段:
real_ip_header X-Forwarded-For; - 把 zone 改为:
limit_conn_zone $realip_remote_addr zone=perip:10m;
增强可控性与可观测性
让限流行为更明确、更容易排查:
-
limit_conn_log_level warn;或error;,避免日志刷屏 -
limit_conn_status 429;返回 429 Too Many Requests,语义比默认 503 更清晰 - 搭配
limit_req使用:HTTP/2 下单连接可承载大量请求,仅靠 limit_conn 不够,建议补一层请求速率限制 -
keepalive_timeout 15;及时释放空闲长连接,避免无效占用配额











