least_conn算法通过将新请求优先分发给当前活跃连接数最少的健康后端,动态缓解任务积压;需配合健康检查、upstream keepalive(如32)及后端连接复用,并用max_conns适配性能差异,再协同超时与重试机制才能真正生效。

怎么让 least_conn 真正起效
光写一行 least_conn; 不够,得配齐三件事:
-
健康检查必须开启:否则宕机但 TCP 连接未断的节点,连接数可能还是 0,Nginx 会继续往里发请求。建议用主动探测:
health_check interval=3 fails=2 passes=2,配合状态码和响应体校验 -
upstream keepalive 要设合理值:比如
keepalive 32。太小导致频繁建连,太大则空闲长连接虚高连接数,干扰判断。注意:keepalive 连接会计入活跃总数 -
后端要支持连接复用:HTTP/1.1 需返回
Connection: keep-alive,HTTP/2 默认支持;Nginx 侧加上proxy_http_version 1.1; proxy_set_header Connection '';
应对性能差异大的后端
least_conn 本身不认 weight,但你可以用 max_conns 表达承载力差异:
- 高性能节点设
server 10.0.1.10:8080 max_conns=2000; - 普通节点设
server 10.0.1.11:8080 max_conns=800; - 超过上限的请求会被跳过,自动选下一个连接数最少且未超限的节点
配合超时与重试防卡死
即使用了 least_conn,如果后端响应慢或失败,请求仍可能滞留。需协同配置:
-
proxy_connect_timeout 2s:建连别拖太久 -
proxy_read_timeout 15s:略大于业务最长耗时,避免误杀慢请求 -
proxy_next_upstream error timeout http_502 http_504:遇到这些错误立即换节点,不重试原路
验证是否真在减少积压
别只看平均响应时间,重点盯这些指标:
- 各后端的
active connections(通过stub_status或 Prometheus)是否趋于均衡?是否有个别节点长期接近max_conns? -
$upstream_header_time稳定但$upstream_response_time持续升高 → 积压发生在后端业务层 - 日志中
$upstream_addr分布是否随负载变化动态偏移?而不是固定打到某台机器


















