nginx 通过 limit_conn 限制并发连接数,需先在 http 块用 limit_conn_zone 定义共享内存区域,再在 server 或 location 中用 limit_conn 绑定区域并设上限;代理环境下应配合 realip_module 使用 $realip_remote_addr,并可配置日志等级、返回状态码及限速增强可控性。

配置 limit_conn 限制并发连接数,关键在于两步:先定义共享内存区域记录连接状态,再在具体作用域启用限制规则。它不依赖额外模块安装(ngx_http_limit_conn_module 默认已编译进 Nginx),只需正确写配置即可生效。
定义共享内存区域(必须在 http 块)
这是整个机制的基础,必须放在 http 块中,不能写在 server 或 location 里:
- 使用
limit_conn_zone指令,语法为:limit_conn_zone key zone=name:size; - 常用 key 是
$binary_remote_addr(压缩后的客户端 IP,更省内存) - name 是自定义区域名,后续
limit_conn会引用它,需全局唯一 - size 推荐从
10m起(约支持 16 万~32 万个独立 IP),若日志出现cannot add connection,说明内存不足,需增大
示例:
http {limit_conn_zone $binary_remote_addr zone=perip:10m;
}
在 server 或 location 中启用限制
用 limit_conn 指令绑定前面定义的区域名,并设定每个 key 允许的最大并发连接数:
- 语法:
limit_conn zone_name number;,其中number必须是具体数字 - 可放在
http、server或location块,作用范围越小越精准 - 若多层都配置(如
server和location),以数值更小的那个为准 - 注意:它统计的是当前活跃 TCP 连接(含 keepalive、HTTP/2 多路复用),不是请求数
示例(限制每个 IP 最多 5 个并发连接):
server {location /api/ {
limit_conn perip 5;
}
}
代理环境下的真实 IP 识别
如果 Nginx 前有 CDN、WAF 或负载均衡器,$binary_remote_addr 默认是代理节点 IP,需配合 real_ip_module:
- 确认已加载
http_realip_module(主流发行版默认启用) - 用
set_real_ip_from声明可信上游网段(如192.168.0.0/16或云厂商指定地址) - 改用
$realip_remote_addr作为limit_conn_zone的 key,更可靠 - 避免直接信任
$http_x_forwarded_for,除非已做严格校验和清洗
增强可用性与可观测性
基础限制之外,加几行配置能让行为更合理、排查更方便:
-
limit_conn_log_level warn;—— 把超限日志设为 warn 级,避免 error 日志被刷屏 -
limit_conn_status 429;—— 返回429 Too Many Requests,语义比默认 503 更明确 -
limit_rate 256k;—— 对已放行的连接限速,防止单连接持续占满带宽 - 搭配
limit_req(如limit_req zone=perip burst=10 nodelay;)可防“低连接+高请求”绕过











