max_conns仅在Nginx≥1.11.5、使用least_conn或ip_hash算法、启用keepalive且合理设值时才有效,它限制单台后端出向并发连接数,但不感知后端真实负载,需搭配长连接、排队机制及监控验证。

max_conns 不是“硬性保护开关”,它只在特定条件下起作用,用错就等于没设。 它限制的是 Nginx 到单台后端 server 的**出向并发连接数**,但是否真能拦住流量、防止压垮,取决于 Nginx 版本、负载算法、连接复用配置和后端真实承载能力的匹配程度。
必须满足的生效前提
这个参数不会自动生效,缺一不可:
- Nginx 版本 ≥ 1.11.5(旧版本直接忽略该参数)
- upstream 使用的负载均衡算法必须支持连接计数——目前只有 least_conn 和 ip_hash 会检查 max_conns;默认的 round_robin 完全无视它
- 每个 worker 进程独立计数:若启用了多个 worker,实际总连接数可能超过 max_conns × 1,因为各 worker 不共享连接计数器(仅通过共享内存粗略协调)
为什么常设了却没效果?关键误区在这儿
很多人以为只要写上 max_conns=200,后端就绝对收不到第 201 个连接。但现实往往不是这样:
- 没配 keepalive:Nginx 默认用短连接,每次请求建新 TCP 连接、响应完立刻断开。连接生命周期极短,max_conns 很难被持续打满,瞬时并发照样冲过去
- 后端自身瓶颈不匹配:比如 Tomcat 的 maxConnections=150,你却给 Nginx 配 max_conns=300,多余请求仍会被发过去,导致 Connection refused 或排队超时
- 它不感知后端真实负载:CPU 占满、GC 频繁、线程池耗尽……这些 max_conns 全然不知,只认“已建立的 TCP 连接数”
真正起保护作用的配置组合
单靠 max_conns 不够,要搭配以下几项才能形成有效防线:
- 启用长连接:
upstream backend { keepalive 64; },并在 location 中透传 HTTP/1.1 长连接头:proxy_http_version 1.1;+proxy_set_header Connection ''; - 选用合适算法:
least_conn是最稳妥的选择,它既按活跃连接数分发,又尊重 max_conns 限制 - 合理设值:基于压测结果确定后端单实例稳定并发上限(如响应时间开始明显上升的拐点),max_conns 设为该值的 80%~90%,留缓冲余量
- 加排队机制(推荐):Nginx 开源版 1.23.3+ 或 Nginx Plus 支持
queue=10 timeout=30s,超出 max_conns 的请求进入队列等待,而不是直接拒绝
验证与监控不能少
设完不看效果,等于白设:
- 开启
nginx_stub_status或使用nginx-module-vts,实时查看各 upstream server 的 Active connections 是否贴近设定值 - 配合 access_log 记录
$upstream_addr和$upstream_response_time,识别是否出现大量超时或转发到已满节点 - 观察后端日志中的连接拒绝、线程池满、503 错误率,反向校验保护是否到位


















