least_conn本身无法识别死锁节点,必须配合被动健康检查(max_fails/fail_timeout)、proxy_next_upstream错误重试、合理超时设置及keepalive连接复用才能有效规避。

要防止单台后端机器因死锁、卡顿或响应停滞导致请求持续堆积,Nginx 的 least_conn 算法本身不能单独起效——它只比较“当前活跃连接数”,但若节点已死锁却仍维持 TCP 连接(如线程阻塞、GC 停顿、数据库锁未释放),连接数不会归零,Nginx 仍会不断把新请求发过去。真正起作用的是与 least_conn 协同的健康感知机制。
必须配置被动健康检查(fail_timeout + max_fails)
这是拦截死锁节点的第一道防线。Nginx 需通过实际请求失败来识别异常,而非仅依赖连接数:
- 每个
server行必须显式配置max_fails和fail_timeout,例如:server 10.0.1.10:8080 max_fails=2 fail_timeout=15s; - 当该节点连续 2 次返回超时(
proxy_connect_timeout或proxy_read_timeout触发)、502/500 或连接拒绝,Nginx 就在 15 秒内将其标记为不可用,不再纳入 least_conn 选择范围 - 避免设
max_fails=0或完全不写——这等于关闭被动检查,死锁节点将永远参与调度
启用 proxy_next_upstream 错误重试兜底
让失败请求能自动流转到其他健康节点,而不是卡死在问题机器上:
- 在
location或upstream外层添加:proxy_next_upstream error timeout http_500 http_502; - 特别关键的是
timeout:若后端因死锁无法响应,Nginx 在proxy_read_timeout超时后立即重试,同时触发max_fails计数 - 不要漏掉
http_502:后端过载或进程崩溃常返回 502,这是最直接的死锁/宕机信号
合理设置超时参数,避免“假忙”长期占位
死锁往往表现为响应无限延迟,超时设置不当会让连接长时间挂起,虚高连接数:
-
proxy_connect_timeout 5s;:建连阶段超时,防服务端端口无响应 -
proxy_read_timeout 30s;:读取响应超时,需略大于后端最长正常耗时(如报表接口设 60s),但绝不能设为 0 或过大(如 300s) -
proxy_send_timeout 10s;:客户端上传慢时控制发送阶段,防止大文件上传卡住连接
配合 keepalive 与后端连接池,减少连接泄漏干扰
死锁常伴随连接泄漏(socket 未 close),导致 Nginx 统计的 “active connections” 持续偏高:
- upstream 内启用:
keepalive 32;,并确保后端开启连接复用(如 Tomcat 设置maxKeepAliveRequests > 0) - location 中强制 HTTP/1.1 并清空 Connection 头:
proxy_http_version 1.1;<br>proxy_set_header Connection '';
- 定期用
ss -tan | grep :8080 | grep ESTAB | wc -l登录后端核对真实 ESTABLISHED 连接数,若远高于 Nginx 的Active connections,说明存在泄漏,需排查后端代码或框架配置


















