必须在main块配置worker_shutdown_timeout(如60s),它是在Nginx热加载时强制退出卡在shutting down状态旧worker的唯一有效机制,需同步调大proxy_read/send_timeout、合理设置client_*_timeout及WebSocket相关参数,否则无法稳定生效。

要强制关闭因死连接卡在 shutting down 状态的旧 Worker 进程,关键不是“绕过”机制,而是正确启用并调优 worker_shutdown_timeout——它本身就是 Nginx 为解决这类问题而设计的强制退出安全阀。
为什么旧 Worker 会卡在 shutting down 不退出
默认情况下,Nginx reload 后,旧 Worker 收到 QUIT 信号,会立即停止 accept 新连接,但不会主动关闭已建立的 TCP 连接。如果某个连接处于异常状态(如客户端断网未发 FIN、中间网络设备静默丢包、或应用层未响应),该连接就变成“死连接”:既不传输数据,也不自然断开。Nginx 会无限等待它结束,导致进程长期滞留、内存和文件描述符持续占用,ps 中持续显示 shutting down。
worker_shutdown_timeout 是唯一有效的强制手段
这个指令不是“辅助选项”,而是自 1.19.10 起强制生效的核心控制开关。它明确告诉 Nginx:“旧 Worker 最多再服务已有连接 X 时间,超时后不管连接是否活跃,一律强制 close socket 并退出进程”。
- 必须写在 main 块(nginx.conf 最外层),写在 events/http/server 内完全无效
- 单位支持
s(秒)、m(分),例如worker_shutdown_timeout 60s;或2m; - 设为
0表示禁用该机制,退回到无限等待(不推荐)
针对死连接场景的合理取值建议
死连接往往没有明确业务耗时,但有可观测的“空闲僵直窗口”。配置应覆盖网络层和中间设备的典型静默容忍极限:
- 若使用云负载均衡(如阿里云 SLB、AWS ALB),其默认空闲超时多为 60–300 秒,
worker_shutdown_timeout应略大于该值(例如设为360s) - 若部署在 Kubernetes 中,配合
terminationGracePeriodSeconds(通常 30s),建议设为45s~60s,确保 Nginx 先于 Pod 强制终止前完成清理 - 若存在 NAT 网关或防火墙,其连接跟踪表(conntrack)超时常见为 300s(5 分钟),则至少设为
5m - 不建议盲目设极大值(如
1h),否则仍可能堆积;优先结合netstat -ant | grep :80 | wc -l和ss -ti观察实际僵直连接的 RTO/RTT 分布
配套必须同步调整的超时项
仅设 worker_shutdown_timeout 不足以让强制退出稳定生效。以下参数必须对齐,否则会出现“超时未到先断连”或“超时已到还卡住”:
-
proxy_read_timeout和proxy_send_timeout必须 ≥worker_shutdown_timeout,否则 Nginx 会在后端响应前主动断开连接,导致旧 Worker 无法等到真正超时就提前放弃 -
client_header_timeout和client_body_timeout应 ≤worker_shutdown_timeout,防止慢速攻击或异常客户端长时间不发完请求头/体,把旧 Worker 拖住 - 对 WebSocket 等长连接,还需配
proxy_read_timeout 86400;,避免默认 60 秒主动断开干扰 shutdown 倒计时

















