least_conn是nginx基于实时活跃连接数的负载均衡策略,仅将新请求分发给当前连接数最少的可用后端,不感知响应时间或超时;节点健康状态依赖独立的被动(max_fails/fail_timeout)或主动健康检查机制。

least_conn 是 Nginx 负载均衡的一种策略,它将新连接分配给当前活跃连接数最少的上游服务器,并**不主动探测节点健康状态**,也不基于响应时间或超时做动态剔除。也就是说:它本身**没有“超时未响应判定机制”** —— 这个逻辑不在 least_conn 内部,而依赖于 upstream 的 health check(主动健康检查) 或 fail_timeout / max_fails(被动健康检查) 配置。
1. least_conn 本身不处理超时判定
least_conn 只在每次新建连接时,统计各 upstream server 的 ngx_connection_t 活跃连接数(即已建立但尚未关闭的 TCP 连接数),选最小者转发。它:
- 不关心后端是否响应慢、是否超时、是否返回 5xx
- 不记录单次请求耗时,也不维护 RTT 或失败历史
- 不会因为某次 proxy_read_timeout 触发就标记该节点为“不可用”
2. 超时导致节点被摘除,实际由 passive health check 控制
当某个 upstream server 出现超时(如 proxy_connect_timeout、proxy_read_timeout、proxy_send_timeout),Nginx 默认会将其视为一次“失败”,并按以下规则累计:
- 每次失败(连接拒绝、超时、返回 500/502/503/504 等)计 1 次 fail
- 若
max_fails在fail_timeout秒内达到,则该 server 被标记为“unavailable”,在此期间不再参与 least_conn 选择 - 默认
max_fails=1,fail_timeout=10s(注意:不是 60s!)
✅ 排查建议:
- 查看 error.log 中类似 upstream timed out (110: Connection timed out) 或 no live upstreams 的日志
- 检查 upstream 块中是否显式配置了 max_fails 和 fail_timeout,例如:
upstream backend {
least_conn;
server 192.168.1.10:8080 max_fails=3 fail_timeout=30s;
server 192.168.1.11:8080 max_fails=3 fail_timeout=30s;
}3. 主动健康检查(nginx plus / openresty / nginx 1.11.5+ with http_healthcheck_module)可替代被动机制
开源版 Nginx(http_healthcheck_module,可通过 health_check 指令实现基于 HTTP 探针的实时判定:
- 定期 GET 某个健康接口(如
/health) - 根据响应状态码、body、耗时等判断存活
- 失效节点直接从 least_conn 候选池中移除,不参与连接数统计
⚠️ 注意:主动检查需单独启用,且与 max_fails 互斥(一旦启用 health_check,被动检查自动禁用)。
4. 如何确认某个节点是否已被 least_conn “忽略”?
最直接的方式是结合日志和监控:
- 开启
log_format记录$upstream_addr和$upstream_status,观察某 IP 是否长期未被选中或频繁出现502/504 - 用
stub_status或nginx-module-vts查看各 upstream server 的 active conn 数、requests、fails、unavailable 时间 - 手动模拟超时(如 iptables DROP 后端端口),观察 error.log 中 fail 计数及
upstream ... unavailable提示
如果发现节点明明已不可达,却仍在 least_conn 中被持续选中,大概率是:没配 max_fails / fail_timeout,或值设得过大,或 upstream server 被标记为 unavailable 后又快速恢复(fail_timeout 时间一过就重新加入)。











