least_conn不实现无损重启,仅将新请求发给连接数最少的健康节点;无损重启需后端主动摘除、draining配合Nginx reload及超时对齐。

least_conn 本身不负责“无损重启后端服务器”,它只管把新请求发给连接数最少的健康节点。真正实现后端平滑重启(即旧连接不中断、新请求不打到正在下线的节点),需要 Nginx 配合后端服务协同完成,核心是“主动摘除 + 连接 draining + 客户端兼容”。
后端节点下线前必须主动摘除
不能等连接自然断开或靠超时被动剔除,否则 least_conn 仍可能把新请求分发过去。正确做法是:
- 在 upstream 中为待下线节点临时加 down 标志:
server 192.168.1.10:8080 down; - 执行
nginx -s reload—— 此刻该节点立即停止接收新连接,但已有长连接继续处理 - 若用健康检查(如
max_fails=1 fail_timeout=10s),也可先让节点主动返回 503,触发快速失败摘除
后端服务自身要支持 draining 模式
Nginx 只控制转发逻辑,不干预后端生命周期。要确保旧连接能跑完,后端需配合:
- 收到 SIGUSR2 或 HTTP /drain 接口调用后,停止 accept 新连接
- 保持已建立连接(包括 WebSocket、HTTP/2 流、文件上传)直到业务自然结束或超时退出
- Java(Spring Boot)、Node.js、Go 等主流框架均有成熟 draining 实现,需启用并配置合理 grace period
客户端与代理层超时要对齐
避免因超时错配导致连接被 Nginx 或后端单方面关闭:
-
proxy_read_timeout必须 ≥ 后端 draining 超时时间(例如设为 300s) -
proxy_send_timeout同理,覆盖大文件上传等慢写场景 - 客户端侧也要设置合理的连接空闲心跳(如 WebSocket ping/pong ≤
proxy_read_timeout × 0.6)
验证是否真正无损
光看配置不够,需观察实际行为:
- 通过
stub_status查看目标 server 的Active connections是否缓慢下降而非突降为 0 - 抓包或日志确认:新请求不再命中该节点,而旧连接响应码仍为 200,且持续时间符合预期
- 监控
upstream_addr和upstream_response_time,确认无 502/504 或异常延迟


















