worker_shutdown_timeout 是 nginx 1.19.10+ 强制启用的超时机制,必须置于 main 块,用于限制旧 worker 进程在 reload 后等待连接自然关闭的最大时长,超时后强制终止以防止资源滞留。

平滑重载(nginx -s reload)过程中旧 worker 进程卡在 shutting down 状态,本质是 Nginx 在优雅退出阶段被“挂住”,不是配置没生效,而是连接没走完。排查重点不在“能不能启新”,而在“为什么旧的退不掉”。
确认是否真卡住,而非正常等待
执行 ps aux | grep 'nginx: worker process' | grep 'shutting down' 查看进程状态。若持续存在且数量不减(比如 5 分钟后仍有多个),说明异常;若快速减少后归零,属于正常行为。可配合 ss -ti | grep :80 观察连接状态:大量 ESTAB 但无数据收发、RTO 极高或 retrans 次数多,就是典型死连接迹象。
检查 worker_shutdown_timeout 是否启用且位置正确
该指令是强制退出的唯一开关,但极易配错:
- 必须写在
nginx.conf最外层(main 块),即events、http块之外 - 不能写成
http { worker_shutdown_timeout 60s; }—— 这样完全无效 - 设为
0表示禁用,会退回到无限等待,务必避免 - 建议值参考:普通 API 设 30s,Keep-Alive 场景 ≥75s,WebSocket ≥90s
验证上下游超时是否闭环对齐
只设 worker_shutdown_timeout 不够,它要和其它超时形成逻辑链条:
-
proxy_read_timeout和proxy_send_timeout必须 ≥worker_shutdown_timeout,否则 Nginx 会在后端响应前主动断开,导致旧 worker 提前被“悬停” -
client_header_timeout和client_body_timeout应 ≤worker_shutdown_timeout,防止客户端发包太慢把旧进程拖住 - WebSocket 必须配齐:
proxy_http_version 1.1;、proxy_set_header Upgrade $http_upgrade;、proxy_set_header Connection "upgrade";
排查日志与系统级干扰
旧进程卡住常伴随无声故障:
- 查
error.log中是否有[notice] ... shutting down后长期无后续,或反复出现recv() failed (104: Connection reset by peer)类错误 - 若 error.log 空白,立即查
journalctl -u nginx -n 50—— systemd 日志可能记录了 SELinux 拦截、权限拒绝等底层失败 - 云环境需核对负载均衡器空闲超时(如 AWS ALB 默认 3600s),
worker_shutdown_timeout应略小于它,避免 LB 先断连而 Nginx 还在等











