limit_conn_zone是Nginx连接限流的共享内存基础,须在http块中唯一定义;键推荐$binary_remote_addr,内存按64字节/客户端预估,需配合keepalive_timeout释放空闲连接。

在大规模并发场景下,limit_conn_zone 是 Nginx 实施连接数管控的底层基础设施——它不负责限流动作本身,而是为 limit_conn 提供可高速读写的共享内存状态表。真正稳定扛住高并发的关键,不在“设多少上限”,而在于这张表怎么建、建多大、键怎么选、状态怎么维护。
共享内存区域必须放在 http 块,且只能定义一次
这是硬性约束,不是风格建议。Nginx 启动时会将 limit_conn_zone 指令解析为一块跨 worker 进程共享的内存段,所有 worker 共用同一张计数表。如果误写在 server 或 location 里,配置直接报错无法加载。
- 正确写法:limit_conn_zone $binary_remote_addr zone=perip:10m;
- 错误写法:放在 server{} 内、或重复定义同名 zone(如两次写 zone=perip:5m)
- zone 名称(如 perip)后续会被 limit_conn 引用,需全局唯一、命名清晰
键的选择决定限流粒度和内存开销
键(key)是哈希进内存表的依据,直接影响能跟踪多少客户端、是否精准、会不会撑爆内存。
- $binary_remote_addr:推荐首选。4 字节二进制 IP,每个 key 占约 64 字节,10MB 可存约 16 万个独立 IP;比字符串形式的 $remote_addr 节省内存 50% 以上,且无哈希计算延迟
- $server_name:适合多租户网关,按域名隔离连接池,避免某租户独占全部连接资源
- 慎用 $uri 或 $args:一个热门接口带 10 种参数组合,就生成 10 个 key;流量一上来 key 数爆炸,内存迅速耗尽,触发 “zone storage exhausted” 错误
内存大小要按峰值活跃客户端数预估,宁稍余勿紧绷
共享内存不是缓存,不淘汰旧条目;当新客户端到来而内存已满时,Nginx 会直接拒绝其连接(返回 limit_conn_status 状态码),不踢旧连接、不降级处理。
- 估算公式:预期最大活跃 IP 数 × 64 字节 ≈ 所需 zone 大小
- 例如:预估高峰有 20 万真实用户访问,至少配 zone=perip:12m(200000×64÷1024÷1024≈12.2)
- 若只配 5m(约支持 8 万个 key),高峰期每第 9 个新 IP 就可能被误限——这不是策略生效,而是资源不足导致的失效
配合 keepalive_timeout 和日志控制提升稳定性
连接数限制生效于 TCP accept 阶段,但空闲 keepalive 连接仍长期占用配额。不加管控会导致“连接僵尸化”,实际并发未增,但配额被无效占满。
- 设置 keepalive_timeout 15;:让空闲连接 15 秒后自动断开,及时释放配额
- 启用 limit_conn_log_level error;:把限流日志从 warn 提到 error 级别,避免海量 warn 日志刷屏、掩盖真正故障
- 指定 limit_conn_status 503; 或 429;:明确语义,方便上游识别是容量受限而非服务异常










