least_conn在微服务中需验证是否真实感知负载差异并动态避让高连接节点;需构造响应不均环境、用wrk分阶段压测、对比round-robin基线、校验健康检查与keepalive对齐。

测试 Nginx 的 least_conn 在微服务集群中的表现,重点不是“它有没有转发”,而是验证它是否真能感知各服务实例的真实负载差异,并据此动态避开连接堆积节点、缓解响应不均和隐性排队。微服务场景下,后端异构性强、调用链长、健康状态易波动,单纯启用 least_conn 很容易失效。下面从四个实操维度说清楚怎么测出真实效果。
构造可比、可控的响应不均环境
微服务天然存在响应时间差异(如订单服务快、风控服务慢),但压测必须主动放大并固化这种差异,否则看不出调度倾向:
- 用 mock 服务统一控制各实例响应:例如 service-a 返回固定 100ms,service-b 返回 600ms,service-c 返回 200ms;禁用所有缓存与异步延迟逻辑
- 确保各实例部署独立(不共用进程或容器),避免资源争抢干扰连接数统计
- 关闭 Nginx 的
proxy_cache和无关日志模块,开启stub_status,确保你能实时查到每个 upstream server 的Active connections
用 wrk 分阶段压测 + 实时抓连接分布
ab 工具不支持长连接复用,无法触发 least_conn 的核心判断逻辑;wrk 更贴合微服务典型流量特征:
- 第一阶段:从 500 RPS 起步,每 30 秒 +300 RPS,观察 P95 延迟拐点和错误率(>0.5% 即暂停)
- 第二阶段:在拐点附近稳压 2 分钟,同时采集三类数据:
– Nginx 的nginx_upstream_requests_total和nginx_upstream_response_time_seconds
– 各后端机器的ss -tan | grep :port | grep ESTAB | wc -l
– 每个实例的 CPU、GC 频次、线程池活跃数(用于交叉验证连接数是否真实反映负载)
对比 baseline:换 round-robin 再跑一次
不对比就看不出 least_conn 的价值。同一套压测参数、同一环境,仅把 upstream 中的 least_conn 换成 round_robin(显式声明),再执行完全相同的 wrk 脚本:
- 看连接数极差:least_conn 下三台实例连接数应更接近(如 42/48/51),round-robin 下可能拉大(如 35/58/72)
- 看慢节点错误率:若 service-b 响应慢,least_conn 应显著降低其请求占比,而 round-robin 仍平均分配,导致其 502 错误明显上升
- 看整体 P95 收敛性:least_conn 生效时,P95 延迟曲线应更平缓,突增幅度小
验证健康检查与 keepalive 是否真正对齐
微服务实例常因 GC 暂停、线程池满、网络抖动短暂不可用,least_conn 若没及时剔除故障节点,就会持续导流过去:
- 检查是否配置了
proxy_next_upstream error timeout http_500 http_502,且每个server行带max_fails=2 fail_timeout=15s - 确认
upstream中有keepalive 32,且 proxy 层设置了:proxy_http_version 1.1;proxy_set_header Connection ''; - 在后端服务侧验证连接复用:比如 Spring Boot 应设
server.tomcat.connection-timeout=-1,Tomcat 应开maxKeepAliveRequests > 0,避免 Nginx 想复用,后端却主动断连造成连接数虚低


















