Nginx 的 limit_conn 模块通过定义共享内存区域(http 块中用 $binary_remote_addr)并引用 zone 限制单个 IP 并发连接数,作用于已建立 TCP 连接,需配合 realip 模块识别真实 IP,并建议搭配 limit_req 和 429 状态码增强可控性与可观测性。

要用 Nginx 的 limit_conn 模块限制单个 IP 的并发连接数,核心是两步:先定义共享内存区域统计 IP 连接状态,再在具体作用域启用限制规则。它限制的是已建立、尚未关闭的 TCP 连接数(含 keepalive、HTTP/2 多路复用),不是请求数或速率。
定义共享内存区域(必须在 http 块)
这是前提,缺了这步 limit_conn 完全不生效:
- 使用
$binary_remote_addr作为 key,比$remote_addr更省内存(IPv4 固定 4 字节,IPv6 固定 16 字节) - zone 名称要唯一,大小按业务规模预估:10MB 约支持 16 万个独立 IP,百万级用户建议设为 20m 或更高
- 必须写在
http{}最外层,不能嵌套在server或location里,否则启动报错
示例配置:
limit_conn_zone $binary_remote_addr zone=perip:10m;
在 server 或 location 中启用限制
引用上面定义的 zone 名,并设定每个 IP 允许的最大并发连接数:
- 写在
server块中,对整个站点生效;写在location /api/中,只限制该路径 - 若多个作用域都配置了
limit_conn,以数值更小的那个为准 - 注意:它对静态资源(如图片、CSS)也生效,但对未进入 upstream 的请求(如直接返回 404)不计数
示例:
server {
limit_conn perip 10;
}
代理环境需正确识别真实 IP
如果 Nginx 前有 CDN、WAF 或负载均衡器,$binary_remote_addr 默认拿到的是代理节点 IP:
- 确保已加载
http_realip_module - 用
set_real_ip_from指定可信上游网段 - 改用
$realip_remote_addr作为 key,或从$http_x_forwarded_for提取第一个非空 IP 并清洗空格
增强实用性与可观测性
让限流行为更可控、更易排查:
- 加
limit_conn_log_level error;把超限日志设为 error 级,避免刷屏 - 设
limit_conn_status 429;返回 429 Too Many Requests,语义比默认 503 更明确 - 配合
map和自定义log_format,在 access 日志中标记被限流请求,便于后续分析或对接 fail2ban - HTTP/2 场景下单靠
limit_conn不够精准,建议叠加limit_req控制每秒请求数兜底


















