least_conn与keepalive需协同配置才能实现长连接复用:least_conn仅按连接数调度,keepalive按worker+server维护独立连接池,若调度频繁跳转则连接池无法复用;必须显式配置keepalive、least_conn置首行、禁用weight改用max_conns、启用http/1.1并清除connection头、后端支持keep-alive、避免proxy_buffering阻塞连接释放。

Nginx 的 least_conn 算法本身只管“选连接最少的后端”,它不负责复用连接,也不感知连接是否空闲。真正让长连接高效复用的,是 keepalive 指令——但二者必须正确配合,否则 least_conn 会频繁切换目标 server,导致每个后端的 keepalive 连接池长期得不到复用,最终退化为短连接。
关键不是“用了 least_conn + keepalive”,而是“让 least_conn 的调度不破坏 keepalive 的复用路径”。
为什么 least_conn 容易让 keepalive 失效
-
keepalive N是按 每个 worker 进程 + 每个 upstream server 维护独立连接池的; -
least_conn会动态把新请求打向当前连接数最少的 server; - 如果各 server 连接数接近,请求就会在多个节点间来回跳转;
- 结果:每个 server 的 keepalive 连接池刚建好一两个,就被闲置超时回收,新请求来又得重建连接。
让 least_conn 和 keepalive 协同工作的硬性条件
- upstream 块中必须显式写
keepalive 32(数值建议 16–64,视后端并发能力而定); -
least_conn必须放在 upstream 首行,且所有 server 不设weight(改用max_conns控制上限); - location 中必须启用
proxy_http_version 1.1并清除 Connection 头:proxy_http_version 1.1; proxy_set_header Connection '';
- 后端服务必须支持并开启 keep-alive(如 Tomcat 的
keepAliveTimeout > 0,Swoole/Workerman 显式启用open_tcp_keepalive); - 避免
proxy_buffering on(尤其对流式响应),否则连接可能被阻塞无法及时释放回池。
实际配置示例(精简可靠版)
upstream api_backend {
least_conn;
server 10.0.1.10:8000 max_conns=256;
server 10.0.1.11:8000 max_conns=256;
keepalive 32;
}
server {
location /api/ {
proxy_pass http://api_backend;
proxy_http_version 1.1;
proxy_set_header Connection '';
proxy_connect_timeout 15s;
proxy_send_timeout 300s;
proxy_read_timeout 300s;
}
}
验证是否真正复用成功
- 用
ss -s | grep ESTAB查看 Nginx 到各后端的 ESTABLISHED 连接总数,稳定在worker_processes × keepalive附近(比如 4 个 worker + keepalive 32 → 约 128 条空闲连接); - 在 access log 中加
$connection_requests字段,观察单个连接平均处理请求数:若 ≥ 5,说明复用有效;若始终为 1,就是短连接; - 检查后端监控中的 active connections,应明显低于 QPS × 平均响应时间(例如 QPS=200、avg RT=0.3s → 理论连接数≈60;若实际达 2000,说明 keepalive 未生效)。
不复杂但容易忽略。











