Nginx连接数限制需在http块中用limit_conn_zone定义共享内存池(如zone=addr:10m),再于server或location中用limit_conn addr 10生效;key推荐$binary_remote_addr,内存大小按预期key数×64~128字节估算。

要配置 Nginx 的连接数限制,核心是用 limit_conn_zone 定义共享内存池,再配合 limit_conn 指令生效。关键在于 zone 名称、key 的选择、内存大小设置是否合理,否则会不起作用或导致内存浪费。
limit_conn_zone 的语法和参数含义
limit_conn_zone 必须放在 http 块中,用于声明一个基于特定 key(如客户端 IP)的连接计数器,并分配一块共享内存区域供 worker 进程共用。
基本写法:
limit_conn_zone $binary_remote_addr zone=addr:10m;
-
$binary_remote_addr:推荐用这个变量替代
$remote_addr,它以二进制格式存储 IP 地址(IPv4 固定 4 字节,IPv6 固定 16 字节),更省内存、查找更快; -
zone=addr:10m:定义名为
addr的共享内存池,大小为 10MB; - 10MB 内存大约能存储 16 万个独立 key(按平均每个 key 占用约 64 字节估算),实际容量取决于 key 长度和系统架构;
- 不能写在
server或location块里,否则启动报错。
如何绑定连接限制到具体作用域
定义好 zone 后,需在 server 或 location 块中使用 limit_conn 指令启用限制:
server {
limit_conn addr 10; # 每个 IP 最多 10 个并发连接
}- 该指令限制的是同一 key(这里是
$binary_remote_addr)在同一 zone 下的活跃 TCP 连接总数; - 如果同时配置了多个
limit_conn(比如不同 zone),Nginx 会取最严格的那个(即最小值); - 注意:它限制的是「当前保持的连接数」,不是请求数(那是
limit_req干的事); - 若想对整个虚拟主机统一限流,放
server块;若只针对上传路径,可放在location /upload中。
共享内存池大小怎么估算才不爆或不浪费
内存池太小会导致 key 频繁淘汰、统计不准;太大则浪费资源。估算公式参考:
所需内存 ≈ (预期最大独立 key 数) × (64 ~ 128 字节/entry)
- 例如:预估最多有 50 万个不同客户端访问,按 100 字节/entry 算,约需 50MB;
- 生产环境建议从 10m 起步,观察日志中的
limit_conn拒绝记录和nginx -t提示; - 可用
nginx -V 2>&1 | grep -o 'with-http-limit-conn-module'确认模块已编译; - 运行中可通过
curl -I http://localhost/nginx_status(需启用 stub_status)或监控ngx_http_limit_conn_module相关指标辅助调优。
常见误区和调试技巧
很多配置看似正确却没效果,往往卡在这几个点:
- 把
limit_conn_zone写在server块里 → 启动失败,提示 “invalid number of arguments”; - 用了
$remote_addr而不是$binary_remote_addr→ 内存占用翻倍,key 冲突率上升; - 未考虑代理场景:如果 Nginx 前有 CDN 或负载均衡,
$binary_remote_addr变成上游地址,应改用$http_x_forwarded_for并做可信校验; - 测试时用 curl 默认短连接,看不出效果,建议用
ab -n 100 -c 50 http://xxx/或weighttp -n 100 -c 30 -k URL持久化压测; - 拒绝响应默认返回 503,可通过
limit_conn_log_level error和error_log ... notice查看被限连的 client IP。


















