least_conn策略仅基于Nginx各worker到后端的实时活跃连接数进行调度,通过原子计数器在事件循环内轻量维护与更新,线性扫描选取最小连接数节点,不依赖系统指标或跨worker同步,需配合keepalive才能有效反映真实压力。

Linux 下 Nginx 的 least_conn 策略不是靠外部监控或系统指标(如 CPU、内存)驱动的,它只依赖一个轻量、确定性的内部状态:Nginx 自身与每个后端服务器之间当前已建立、尚未关闭的 TCP 连接数。
核心是连接计数器,不是负载感知
Nginx 在 upstream 模块中为每个 server 维护一个原子递增/递减的整型计数器,记录“本机到该后端的活跃连接数”。这个计数器在以下时刻更新:
- 当 Nginx 成功与后端建立新连接(例如 proxy_pass 第一次发起连接,或 keepalive 复用连接失败需新建时)→ 计数器 +1
- 当该连接被主动关闭(如后端断连、超时、请求结束且未复用)→ 计数器 −1
- 健康检查探测连接不计入该计数(除非显式配置
health_check使用长连接并复用)
它不读取 /proc/net/tcp,也不调用 getsockopt(SO_INCOMING_NAPI_ID) 等系统接口;所有统计完全在 Nginx 事件循环内完成,无系统调用开销。
调度过程是线性扫描,复杂度 O(n)
每次有新请求需要选择后端时(七层 HTTP 或四层 stream),Nginx 执行一次遍历:
- 跳过状态为
down或连续失败触发临时摘除的节点 - 比较剩余健康节点的当前连接计数器值
- 取最小值对应节点;若多个节点计数相同,则按配置顺序(或加权轮询的内部游标)选第一个
这个过程平均耗时在微秒级,官方实测 1000 个后端节点下仍低于 1ms,因为只是内存变量比较,无锁(使用 per-worker 局部计数器+原子操作保证一致性)。
不跨 worker 共享连接数,但效果足够实用
Nginx 多 worker 架构下,每个 worker 进程独立维护自己到后端的连接池和计数器。这意味着:
- 不存在全局统一的“某后端总连接数”,只有“本 worker 到该后端的连接数”
- 不同 worker 可能同时选中同一个后端(只要各自计数都是当前最小)
- 但因请求分发本身由 accept_mutex 或 SO_REUSEPORT 均衡,且连接复用率高,实际压测中仍能显著缓解单点堆积
这种设计牺牲了强一致性,换来了零共享内存、无进程间同步开销,更适合高并发场景。
它和 keepalive 配合才真正发挥价值
least_conn 的有效性高度依赖后端连接复用:
- 如果每次请求都新建+立即关闭连接(短连接),连接数几乎恒为 0 或 1,算法退化为轮询
- 开启
proxy_http_version 1.1和proxy_set_header Connection '',配合后端支持 HTTP/1.1 keepalive,才能让连接长期存在、计数真实反映压力 - 四层 stream 模块同理,需确保
proxy_timeout合理,避免连接过早释放
所以它不是“智能预测负载”,而是“诚实反映当前连接持有状态”的务实策略。











