Nginx least_conn通过实时统计各后端活跃TCP连接数(含keepalive空闲连接)并每次请求时选择该数值最小的健康节点调度,不依赖预测或平均;weight用于加权计算conns/weight比值以适配硬件差异,健康检查与max_conns等机制协同保障异常节点被自动跳过。

least_conn 的原理不是预测或平均,而是每次新请求来时,直接看各后端当前有多少活跃 TCP 连接,挑最少的那个发过去。
它怎么知道谁连接最少
Nginx 在 upstream 模块中为每个 server 维护一个实时计数器,统计从 Nginx 到该后端已建立、尚未关闭的所有 TCP 连接——包括正在处理请求的连接,也包括 keepalive 空闲连接。这个数字就是“活跃连接数”。
- 每收到一个新请求,Nginx 就遍历所有健康可用的 server(已排除 down、max_fails 触发的失败节点)
- 对每个 server 计算 conns / weight 值,而非单纯比 conns
- 选该比值最小的 server;若多个比值相同,则退回到加权轮询顺序选取
权重(weight)在这里起什么作用
weight 不是“优先级开关”,而是调节连接承载能力的标尺:
- 高 weight 的节点,允许拥有更多连接才被判定为“不空闲”
- 比如 A 节点 weight=2、当前连接数=10,B 节点 weight=1、当前连接数=6,则 A 的比值是 5,B 是 6 → 仍选 A
- 它让硬件差异能自然融入调度逻辑,而不是靠人工干预切换节点
哪些连接会被计入“活跃”
只要 TCP 连接还开着,就算活跃:
- 后端正在处理请求的连接
- keepalive 复用中的空闲连接(如 upstream keepalive 32 配置下的待复用连接)
- WebSocket 长连接、gRPC 流式连接等持续打开的通道
- 但不会统计客户端到 Nginx 的连接,只统计 Nginx 到后端的连接
它如何应对节点异常
least_conn 本身不负责发现故障,但会自动配合已有容错机制:
- 被标记为 down 或 backup 的节点,直接不参与比较
- 触发 max_fails / fail_timeout 的节点,在失效期内被跳过
- 若启用主动健康检查(如 ngx_http_upstream_check_module),检测失败的节点也会被临时剔除,恢复后再自动回归调度池
为什么有时选不到“最空闲”的节点
几个常见原因会影响调度灵敏度:
- keepalive 数量设得过大:大量空闲连接长期占用计数,导致连接数迟迟不下降
- 后端响应慢但不断连:连接数少,可能只是因为请求卡住没返回,不是真轻松
- 没有配置健康检查:节点假死(进程僵住但 TCP 连接未断)仍持续收请求
- max_conns 限制太严:某节点达到上限后被跳过,即使它实际负载并不高


















