least_conn在生产环境是否真正均衡,需双向验证:Nginx侧用ss统计到后端的ESTABLISHED连接数,后端侧用ss/netstat/lsof核对真实连接数,并结合业务特征(长连/短连/混合)及压测对比判断合理性。

验证 least_conn 在生产环境是否真正起到连接均衡作用,不能只看日志或凭感觉,得从 Nginx 侧和后端侧双向比对活跃连接状态,并结合业务特征判断是否“均衡”合理。
查 Nginx 自身连接分布(stub_status 是基础)
先确保已开启 stub_status 模块并暴露状态页,例如:
location /nginx_status {
stub_status;
allow 127.0.0.1;
allow 10.0.0.0/8;
deny all;
}
访问该地址后,重点关注 Active connections 和每个 upstream server 的连接计数(需配合 upstream\_zone 或第三方模块才能直接看到各节点连接数;原生 stub_status 不显示 per-server 连接数)。更实用的做法是:用 nginx -T | grep -A 20 "upstream backend" 确认配置加载正确,再通过以下命令间接观察:
- 运行
ss -tnp | grep :8080 | grep ESTAB | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -nr,统计 Nginx 到各后端 IP 的 ESTABLISHED 连接数 - 配合
watch -n 2 '...'持续观察变化趋势,看是否随流量波动动态迁移
核对后端真实 ESTABLISHED 连接数
Nginx 统计的是它自己与后端建立的 TCP 连接,不是后端应用层的线程或协程数。所以必须登录每台后端服务器,执行:
ss -s | grep "tcp:"
netstat -an | grep ":8080" | grep ESTAB | wc -l
lsof -i :8080 | grep ESTABLISHED | wc -l
对比多台机器的数值。如果 least_conn 生效,高峰时段各节点连接数应相对接近(允许小幅波动),而非某台长期高企、其余偏低。若发现 A 节点始终是 B 的 3 倍,就要排查是否:
- 该节点健康检查失败被降权(
max_fails触发但未恢复) - 客户端强制复用连接到固定 IP(如 DNS 缓存未刷新或客户端 keepalive 配置异常)
- 后端主动关闭慢(
tcp_fin_timeout或应用 linger 设置过长),导致连接在 Nginx 侧仍被计为活跃
结合业务连接特征交叉判断
连接数“均衡”不等于“合理”。比如直播服务中,单个 WebSocket 连接可能持续数小时,此时连接数少≠负载低;而支付接口全是毫秒级短连,连接数多反而说明处理快、吞吐高。验证时要分场景看:
- 长连接为主(如 WebSocket/gRPC):关注各节点 ESTABLISHED 数是否趋同,且与 QPS 无强正相关(即高 QPS 节点连接数未必最高)
- 短连接为主:least_conn 效果本就有限,此时连接数天然波动大,应转而观察响应时间 TP99、错误率、后端 CPU/内存是否均衡
- 混合型:重点看慢请求(如导出、查询)是否明显避开已堆积连接的节点——可通过 access.log 中加
$upstream_addr字段,筛选耗时 >2s 的请求,统计其落在哪台后端
用压测做对照实验
最直接的方式是在低峰期做小流量压测:
- 用 wrk 或 hey 发起 100 并发、持续 60 秒的长连接请求(
-H "Connection: keep-alive") - 记录压测前后各后端的 ESTABLISHED 连接增量
- 对比轮询模式下的同样压测结果:若 least_conn 下三台节点增量分别为 32 / 34 / 34,而轮询下为 48 / 22 / 30,则说明 least_conn 正在起效











