least_conn算法通过将新请求优先分发给当前活跃连接数最少的健康后端,有效规避长任务占用节点导致的隐性排队;需配套健康检查、keepalive复用及后端连接池支持才能生效。

最少连接算法(least_conn)能提升后端集群响应敏捷性,关键不在于“选空闲机器”,而在于它让新请求绕开正被长任务占用的节点——比如一个还在处理 8 秒报表的后端,哪怕它 CPU 没跑满,least_conn 也会自然跳过,把请求导向刚完成上个请求、连接数为 0 的节点。这种调度逻辑对计算密集、耗时波动大的服务特别有效。
它真正解决的是“隐性排队”问题
轮询策略按顺序派发,不管后端手头有没有活儿。结果就是:A 节点正在跑三个 6 秒的模型推理,连接数已堆到 15;B、C 节点空闲,却因轮到 A 还得继续塞请求过去。用户端表现为部分请求延迟陡增、超时增多,监控里看到连接数失衡但 CPU 平稳——least_conn 直接盯住这个“已建立未关闭”的连接数,相当于实时读取每台机器的“待办清单长度”,从而避开拥堵点。
必须配齐三样东西,算法才真正起效
-
健康检查不能缺:least_conn 自身不判断节点是否存活。一台后端进程卡死但 TCP 连接没断,它的连接数可能仍显示为 0,Nginx 就会持续转发。需搭配主动健康检查(如
health_check interval=3 fails=2 passes=2)或至少启用被动探测(proxy_next_upstream error timeout http_500 http_502+max_fails=2 fail_timeout=15s) -
keepalive 要对齐配置:只写
keepalive 32不够。必须同时设置proxy_http_version 1.1和proxy_set_header Connection '',否则后端收不到复用信号,连接建了就关,活跃连接数始终≈请求数,least_conn 就退化成伪随机 -
后端要配合连接池:Tomcat 需开启
maxKeepAliveRequests > 0,Spring Boot 应配置server.tomcat.connection-timeout大于 Nginx 的keepalive_timeout,避免 Nginx 想复用,后端已主动断连
连接数相等时,weight 才真正起作用
当两台后端当前活跃连接数都是 5,least_conn 不会随便挑一个,而是退回到加权轮询逻辑:weight 值高的节点被选中的概率更高。这意味着你可以用 weight 反映硬件差异(如 16 核机器设 weight=2,8 核设 weight=1),而不必强依赖 max_conns。不过若想做软性容量控制,max_conns 更直接——比如给高配节点设 max_conns=2000,普通节点限 800,超过即跳过,不参与 least_conn 比较。
验证是否真起效,看这三项指标
- 压测中各后端的
active connections(通过 stub_status 或 Prometheus)是否基本均衡,而非某台长期高于均值 30% 以上 - 日志中
$upstream_addr字段是否随负载变化动态分布,而不是固定打到某台 - 对比
$upstream_connect_time和$upstream_header_time:前者稳定但后者飙升,说明瓶颈在业务逻辑;两者同步升高,可能是 Nginx worker_connections 不足或网络抖动











