least_conn策略资源倾斜主因是其仅统计ESTABLISHED连接数,无视CPU、线程、响应延迟等真实负载,且受长连接滞留、僵尸连接、缺失健康检查等配置放大失真。

least_conn 策略下出现资源倾斜,往往不是算法本身失效,而是它统计的“连接数”与真实业务负载严重脱节。排查重点不在日志有没有报错,而在确认 Nginx 看到的连接状态是否可信、后端是否真能承接请求。
看懂 least_conn 实际在统计什么
least_conn 只数当前 ESTABLISHED 的 TCP 连接,包括:
- 正在处理请求/响应的活跃连接
- keepalive 空闲但未超时的长连接(哪怕后端完全空闲,只要连接没断,就算在内)
- 后端已崩溃或进程僵死,但 TCP 连接尚未被 Nginx 检测到断开的“僵尸连接”
它完全不感知:CPU 是否打满、线程是否阻塞、请求是否排队、响应是否卡在后端逻辑里。如果某台机器因 GC 暂停或数据库锁表而变慢,但连接还挂着,least_conn 就会继续往它身上导流——这就是倾斜的根源。
检查 upstream 配置是否放大失真
以下配置会让 least_conn 的决策越来越偏离实际:
- keepalive 值过大 + keepalive_timeout 过长:比如 keepalive 100; keepalive_timeout 60s;大量空闲连接长期滞留,某节点连接数虚高,被持续跳过
- 缺少健康检查机制:max_fails 和 fail_timeout 未设,或 proxy_next_upstream 仅配 error,漏掉 timeout、http_502 等典型故障信号,导致故障节点仍参与调度
- 未启用主动探测:仅靠被动检查无法发现“TCP 可通、HTTP 不响应”的僵死状态,此时连接数可能很低,但请求全超时
用命令和日志交叉验证真实连接状态
别只信 $upstream_addr 日志或监控图表,要动手查:
- 在 Nginx 本机执行:ss -tnp | grep : | grep ESTAB,对比各后端 IP 的连接数,看是否与 Nginx 内部统计一致
- 开启详细 upstream 日志:log_format upstreamlog '$time_local — $upstream_addr ~ $upstream_connect_time ~ $upstream_header_time ~ $upstream_response_time';,观察是否频繁打到某台且 $upstream_response_time 明显偏高
- 访问 /nginx_status(需启用 stub_status),结合 Prometheus 或自研脚本采集每个 server 的 active connections,看分布是否随流量变化动态调整
临时切换策略快速定位问题
如果怀疑是 least_conn 统计失真,可做最小干预验证:
- 将 upstream 改为 ip_hash 或 round_robin(显式写 weight=1),保持其他配置不变,跑 5 分钟短连接压测(如 wrk -c 100 -t 4 -d 30s)
- 对比两组下各后端的 $upstream_response_time 分布和错误率:若轮询下负载更均衡、延迟更低,基本锁定是 least_conn 的连接数统计不可靠
- 再切回 least_conn,同步调低 keepalive_timeout 至 15s、缩短 keepalive_requests,并加 health_check,观察是否改善


















