平滑重载后旧 worker 长时间卡在 shutting down 是因等待连接自然结束,本质是僵直连接或超时参数未对齐;需通过 ps、netstat/ss、错误日志及四组超时参数闭环检查定位并修复。

平滑重载(nginx -s reload)后旧 worker 长时间卡在 shutting down 状态,本质是它仍在等待已有连接自然结束——而这些连接可能因客户端失联、网络中断、后端响应延迟或配置超时不合理,迟迟不释放。这不是故障,而是 Nginx 的设计行为;但若持续数分钟甚至更久,就说明存在“僵直连接”或超时参数未对齐,需主动排查。
看进程状态和存活时间
执行 ps aux | grep 'nginx: worker process' | grep 'shutting down',确认旧 worker 是否真实存在且长时间不退出。注意两点:
- 刚 reload 后短暂共存是正常的(新旧 worker 并行服务),通常几秒到几十秒内旧进程应陆续退出;
- 若超过 2 分钟仍有大量
shutting down进程,尤其伴随netstat -ant | grep :80 | wc -l或ss -ti显示大量 ESTABLISHED 但无数据传输的连接,基本可判定为僵直连接滞留。
查日志里有没有 abort 或 socket left 告警
打开 Nginx 错误日志(通常是 /var/log/nginx/error.log),搜索关键词:
-
aborting:说明有人手动 kill 过 worker,触发了异常终止流程; -
open socket left in connection:明确提示有连接未清理干净,常伴随 abort; -
worker process is shutting down重复出现但无后续退出记录,说明进程卡住。
这类日志不是配置错误导致的,而是资源释放环节出了问题,重点盯住 reload 前后 1–2 分钟的日志段。
核对关键超时参数是否闭环
旧 worker 不退出,往往因为某一个超时值远小于实际连接生命周期,导致它“想退退不了”。必须检查以下四组参数是否形成合理闭环:
-
worker_shutdown_timeout(主控开关):必须写在
nginx.conf最外层(main 块),例如worker_shutdown_timeout 90s;; -
proxy_read_timeout / proxy_send_timeout:必须 ≥
worker_shutdown_timeout,否则 Nginx 会在 upstream 响应前主动断连,反而让旧 worker 被“悬停”; -
client_header_timeout / client_body_timeout:应 ≤
worker_shutdown_timeout,防慢请求(如大文件上传头迟迟不发完)拖住进程; -
keepalive_timeout:若设为 75s,建议
worker_shutdown_timeout至少 90s;WebSocket 场景下,还需配proxy_read_timeout 86400;防默认 60s 主动断开。
模拟长连接复现并验证修复效果
加一段测试配置快速验证机制是否生效:
location /hold {
add_header Content-Type text/plain;
return 200 "holding for 80s\n";
# 用 sleep 模拟长响应(需启用 ngx_http_perl_module 或用 echo 模块)
}然后:
- 执行
nginx -t && nginx -s reload; - 立即用
curl -v http://localhost/hold发起请求; - 观察该请求是否完整返回(80 秒后),同时旧 worker 是否在约 90 秒后退出。
若请求中途断开或旧进程超时未退,说明超时闭环未对齐,需回头检查参数位置和数值。


















