Nginx least_conn统计的是upstream所有活跃TCP连接,含忙连接、keepalive空闲连接及长连接;优化需合理设keepalive值、启用HTTP/1.1并清除Connection头、监控$connection_requests,并通过ss、后端指标等交叉验证。

长连接场景下,Nginx 连接数统计不准,本质是“活跃连接”定义模糊——它既包含正在处理请求的连接,也包含空闲但未关闭的 keepalive 连接。若不区分,least_conn 会把大量空闲连接误判为负载,导致调度失衡。优化关键不是压低数字,而是让统计真实反映后端压力。
确认 Nginx 实际统计的是什么
Nginx 的 least_conn 算法统计的是每个 upstream server 当前持有的所有活跃 TCP 连接总数,包括:
- 正在传输请求/响应的连接(真正占用资源)
- keepalive 池中维持的空闲连接(只占内存、不占 CPU,但计入总数)
- 尚未关闭的 WebSocket/gRPC 流连接(即使无数据交换)
所以如果你配置了 keepalive 100,而某后端当前有 95 条空闲连接 + 3 条忙连接,Nginx 就会把它记作 98 连接,远高于另一台只有 12 条忙连接的节点。这不是 bug,是设计如此——你得接受这个事实,并据此调参。
让连接数统计更贴近真实负载
核心思路:减少空闲连接对统计的干扰,同时确保复用收益不丢失。
- 合理设置 keepalive 值:不要盲目设大。建议值 = 后端平均并发连接数 ÷ worker 进程数 × 1.2。例如后端稳定承载 3000 连接,Nginx 有 4 个 worker,则 keepalive 设为 90–120 较稳妥;设到 512 就容易“虚高”
- 启用 proxy_http_version 1.1 并清除 Connection 头:避免客户端或后端因 header 冲突提前断连,造成连接反复重建,干扰统计稳定性
- 监控 $connection_requests 变量:在 access_log 中加入该字段,统计单连接平均承载请求数。若普遍 > 10,说明复用充分,空闲连接存在合理;若普遍 ≈ 1,说明 keepalive 实际未生效,需检查客户端行为或后端配置
验证与辅助观测手段
光看 Nginx 日志不够,要交叉验证连接状态是否真实:
- 用
ss -s | grep "tcp:"查看系统 ESTABLISHED 连接总数,再对比curl http://127.0.0.1:8080/nginx_status输出的 active connections。两者比值接近 1 表示 Nginx 统计基本可信;若系统连接数远高于 Nginx 统计值,说明有连接绕过 upstream(如直连后端)或 Nginx worker 未覆盖全部连接 - 检查后端服务自身连接数指标(如 Tomcat 的 currentThreadCount、Redis 的 connected_clients),和 Nginx 记录的 upstream 连接数做趋势比对。若长期背离,说明后端连接池未复用或存在连接泄漏
- 开启自定义日志格式,记录
$upstream_addr和$upstream_connect_time,分析各节点建连耗时分布。异常高的建连延迟往往意味着连接池已满,被迫新建连接,此时 Nginx 统计的“连接数”虽高,但实际是故障信号而非负载信号


















