Nginx 通过 limit_conn_zone 和 limit_conn 实现基于客户端 IP 的全局限流,基于共享内存 zone 统计并发连接数,限制 TCP 连接建立阶段的活跃连接数而非请求数。

通过 limit_conn_zone 可以在 Nginx 的 HTTP 层实现对客户端并发连接数的全局限制,其核心是基于指定变量(如 $binary_remote_addr)创建共享内存区域,在 worker 进程间共享计数状态。
定义全局连接计数区域
在 http 块中使用 limit_conn_zone 指令声明一个共享内存 zone,用于存储连接数统计:
http {
limit_conn_zone $binary_remote_addr zone=addr:10m;
}说明:
-
$binary_remote_addr是最常用键,表示客户端 IP 的二进制格式(比 $remote_addr 更省内存) -
zone=addr:10m表示创建名为addr的共享内存区,大小为 10MB,足够存储约 16 万个独立 IP 的连接状态 - 该 zone 在所有 worker 进程间共享,天然支持“全局”计数(非单 worker 局部)
在 server 或 location 中启用连接限制
仅定义 zone 不生效,需在具体作用域用 limit_conn 启用:
server {
listen 80;
location /api/ {
limit_conn addr 10; # 每个 IP 最多 10 个并发连接
proxy_pass http://backend;
}
}注意:
-
limit_conn addr 10表示对当前 zone(addr)中每个唯一键(即每个 IP)限制最大连接数为 10 - 该限制作用于 TCP 连接建立阶段(accept 后、request 解析前),适用于长连接、HTTP/2 多路复用等场景
- 若需按域名或 URI 分组限制,可改用其他变量,如
$host、$uri,但需注意内存开销和语义合理性
配合 limit_rate 和日志观察效果
单纯限连可能不够直观,建议搭配响应控制与日志辅助验证:
- 被拒绝连接时,Nginx 默认返回 503,并记录到 error_log(级别 info 及以上)
- 可通过
limit_rate对已放行连接限速,避免单个连接占满带宽 - 开启
log_format记录 $connection 和 $connections_active,便于分析实时连接分布
注意事项与常见误区
实际部署中需留意以下关键点:
- IPv4 和 IPv6 地址分别独立计数;NAT 环境下多个用户可能共用一个 $binary_remote_addr,导致误限
- zone 内存不足时新连接会被拒绝,应根据预估 IP 数量合理设置 size(1MB ≈ 1.6 万条记录)
-
limit_conn限制的是“当前活跃连接数”,不是请求数(request count),不要与limit_req混用 - HTTP/2 下一个 TCP 连接可承载多个流,但
limit_conn仍按连接计,不感知流级并发

















