least_conn策略通过均衡后端tcp连接数间接促进系统资源均衡,需在响应不均场景下,同步采集各后端established连接数、p95延迟、cpu利用率等指标,并与round-robin对比验证其有效性。

Nginx 的 least_conn 策略本身不直接控制 CPU、内存或磁盘等系统资源,它只依据Nginx 与后端之间当前活跃的 TCP 连接数做调度。因此,测试它对“系统资源均衡消耗”的影响,本质是验证:在真实长连接+响应不均场景下,该策略能否让各后端节点的实际负载压力(表现为连接堆积、处理延迟、资源占用)更趋一致。
要测出效果,不能只看 Nginx 日志或平均 QPS,得从后端视角抓可归因的指标,并排除干扰项。
关键指标要同步采集后端的真实资源表现
least_conn 的价值体现在后端节点是否被更公平地“使用”,所以必须在每台后端服务器上实时观测:
-
TCP 层连接状态:用
ss -tn state established | grep :端口 | wc -l统计ESTABLISHED数,这是least_conn的决策依据,也是最基础的校验项 -
应用层处理压力:记录每个请求的
upstream_response_time(Nginx access log 中),再按后端 IP 分组计算 P95 延迟和错误率;若某节点延迟持续偏高但连接数却低,说明它可能已卡死但未被踢出 -
系统资源水位:压测中每 10 秒采样一次
top -bn1 | grep "Cpu\|%Cpu",free -m,pidstat -u 1 1 | grep 应用进程,重点对比 CPU 利用率标准差是否随连接数标准差同步收敛 -
连接复用有效性:检查 access log 中
$connection_requests字段——同一连接上处理的请求数应普遍 ≥ 3;若大量为 1,说明 keepalive 未生效,least_conn实际退化为轮询
必须构造响应不均的压测环境
如果所有后端响应时间一致,least_conn 和 round-robin 表现几乎无差别。要激发算法差异,需人为制造“慢节点”:
- 部署两台后端:A 节点固定 sleep 100ms,B 节点固定 sleep 800ms(用 Python Flask 或 Node.js 快速实现)
- 后端禁用任何缓存、关闭异步队列、统一返回相同大小 JSON,确保差异只来自处理耗时
- Nginx upstream 显式配置
keepalive 32,location 中启用proxy_http_version 1.1; proxy_set_header Connection ''; - 健康检查必须开启:
health_check interval=3 fails=2 passes=2 match=status_ok;或至少配proxy_next_upstream error timeout http_500; max_fails=2 fail_timeout=15s
用 wrk 分阶段压测并比对 baseline
单次压测无法说明问题,需有参照:
- 先用
wrk -t4 -c500 -d60s --latency -H "Connection: keep-alive" http://nginx-lb/api/long-poll压测least_conn配置 - 再将 upstream 改为
round-robin(注释掉least_conn),其他条件完全不变,重跑一次 - 对比两次结果中的三项关键数据:
- 各后端
ESTABLISHED连接数的标准差(least_conn下应明显更小) - B 节点(慢节点)的 P95 延迟增幅(
least_conn应显著抑制其恶化速度) - 两节点 CPU 利用率极差(如 A 为 65%,B 为 82% → 极差 17%;
least_conn下应压缩至 ≤ 10%)
- 各后端
常见失衡原因要提前排查
观察到资源不均,大概率不是 least_conn 失效,而是环境干扰:
- 某节点连接数长期偏高:检查其
upstream_response_time是否显著更长,确认是否因慢响应导致连接堆积未释放 - 所有节点 CPU 都低但连接数差异大:可能是 keepalive 值过大(如设为 256),空闲连接占满“账面名额”,Nginx 误判为“忙”
- 某节点始终零连接:先查健康检查是否将其标记为 down,再确认该节点防火墙或 SELinux 是否拦截了 Nginx 的主动探测包
- 连接数均衡但 CPU 不均衡:说明该节点单连接开销更高(如 TLS 握手更重、GC 更频繁),此时需结合
weight或max_conns做容量适配,而非责怪least_conn
不复杂但容易忽略。











