least_conn是适合混合耗时场景的负载策略,需置于upstream块首行,配合max_conns、keepalive及健康检查使用。

在请求耗时差异大的场景(比如混合了毫秒级 API 和几十秒的 AI 推理、文件导出、流式响应),least_conn 是比轮询(round-robin)更合理的负载策略——它不看权重或响应时间,只把新请求发给当前活跃连接数最少的后端,天然避开那些正被长连接“占着茅坑”的节点。
必须写对位置和基础结构
least_conn 只能作为 upstream 块内的第一条指令,紧接在 upstream 名称之后:
- ✅ 正确:upstream api_cluster { least_conn; server 10.0.1.10:8000; server 10.0.1.11:8000; }
- ❌ 错误:放在 http/server/location 块里 → 启动报错 “directive is not allowed here”
- ❌ 错误:写在 server 行后面,或与 ip_hash、hash、least_time 共存 → 配置校验失败或静默降级
- ❌ 错误:给 server 加 weight → least_conn 会直接忽略,不起作用
用 max_conns 替代 weight 实现容量感知
耗时悬殊常伴随硬件能力差异。不能靠 weight 调度,而要用 max_conns 设置每个节点的连接硬上限,让 least_conn 在真实承载力范围内选最小值:
- 高性能节点(如 GPU 服务器):server 10.0.1.10:8000 max_conns=2000 max_fails=2 fail_timeout=15s slow_start=30s;
- 普通节点:server 10.0.1.11:8000 max_conns=800 max_fails=2 fail_timeout=15s;
- 一旦某节点活跃连接 ≥ max_conns,least_conn 自动跳过,不再参与比较
确保连接数真实反映“手头活儿”
如果后端每次请求都新建再断开 TCP 连接,活跃连接数永远接近 0,least_conn 就退化成随机分配。必须启用长连接复用:
- 在 upstream 块中加:keepalive 32;(每个 worker 最多缓存 32 条空闲连接)
- 在 proxy_pass 所在的 location 中加:proxy_http_version 1.1; 和 proxy_set_header Connection '';
- 后端服务需支持 keep-alive:FastAPI/Uvicorn 调整 --keep-alive;Tomcat 开启 keepAliveTimeout;Node.js 默认支持
防“假空闲”和单点拖垮
连接数少 ≠ 真空闲。可能 TLS 握手卡住、显存不足挂起、或进程僵死但连接未断。必须叠加健康控制:
- 被动检查:配合 proxy_next_upstream error timeout http_500 http_502; 和 server 上的 max_fails=2 fail_timeout=15s
- 主动探测(推荐):用 nginx_upstream_check_module 或 OpenResty 的 https 类型健康检查,每 3 秒探测一次
- 超时协同:在 location 中设 proxy_read_timeout 120;(略高于后端 P99 处理时间),避免长尾阻塞连接复用











