长连接场景必须显式设置worker_shutdown_timeout,否则旧Worker会无限等待连接自然关闭,导致资源长期占用;该指令启用后,Nginx在优雅退出时启动倒计时,超时强制关闭未结束连接,避免shutdown状态滞留。

在长连接业务(如 WebSocket、SSE、大文件上传、HTTP/2 流式响应)中,Nginx 平滑重启若不加控制,旧 Worker 很可能长时间滞留,导致资源占用升高、监控告警误报,甚至触发连接堆积。关键在于合理使用 worker_shutdown_timeout,它不是“可有可无”的配置项,而是决定优雅退出是否可控的开关。
为什么长连接场景必须显式设置 worker_shutdown_timeout
默认情况下,Nginx 不启用超时机制——旧 Worker 会一直等待所有连接自然关闭。而长连接往往由客户端主动维持(keepalive_timeout 默认 75s),或由业务逻辑长期挂起(如未完成的上传、后端未返回的流式响应)。这意味着一个活跃的 WebSocket 连接可能持续数小时,旧 Worker 就会卡住数小时,无法释放内存与 CPU。
设置该指令后,Nginx 才会在进入优雅关闭流程时启动倒计时,避免无限等待:
- 它只作用于已收到 QUIT 信号、进入 shutdown 状态的 Worker 进程
- 倒计时从监听 socket 关闭后开始(即不再接受新连接)
- 超时前,Nginx 主动关闭所有尚未自然结束的连接(包括 keepalive 空闲连接和正在传输中的连接)
如何设置一个合理的超时值
不能拍脑袋定 30s 或 5m。需结合业务特征分层评估:
- 客户端最长空闲容忍时间:比如你的 App 心跳间隔是 45s,那 timeout 至少设为 60s,确保心跳包能被完整处理完
- 典型上传/下载最大耗时:若用户常传 2GB 文件,带宽均值 5MB/s,则理论耗时约 400s,建议 timeout ≥ 480s(预留重试与网络抖动)
- 后端响应最慢链路延迟:如某个 API 平均响应 8s、P99 达 25s,且支持流式输出,则 timeout 应覆盖 P99 × 2~3 倍
生产环境推荐起步值:worker_shutdown_timeout 90s; —— 覆盖常见 keepalive + 中等上传场景,再根据 error.log 中 “worker process is shutting down” 持续时间微调。
配合 reload 的完整操作链
单设参数不够,要嵌入标准运维动作中:
- 修改 nginx.conf,在 events 块或 http 块顶层添加 worker_shutdown_timeout 90s;
- 执行 nginx -t 确认语法正确,避免 reload 卡在配置校验阶段
- 用 nginx -s reload 触发平滑重启(等价于向 Master 发 SIGHUP)
- 观察 ps aux | grep "shutting down",确认旧 Worker 进入 shutdown 状态
- 检查 error.log 是否出现 "exiting" + 对应 PID 日志,且时间戳距 reload 时间 ≤ 90s
若发现大量连接在 timeout 前未关闭,说明业务存在异常长连接(如客户端不发 FIN、后端假死),需配合 tcpdump 或 nginx stub_status 分析连接状态,而非盲目拉长 timeout。
避坑提醒:别手动 kill shutdown 中的 worker
看到 “worker process is shutting down” 状态持续 10 秒就着急 kill -9?这是高危操作:
- 强制终止会导致 socket 句柄未清理,内核报 "aborting connection" 和 "open socket left"
- 可能引发客户端 TCP RST,造成数据截断或重连风暴
- 破坏 Nginx Master 对 Worker 生命周期的管控逻辑,后续 reload 可能失败
只要设置了 worker_shutdown_timeout,就应信任 Nginx 的自动回收机制。真正需要干预的,是排查为何连接迟迟不关闭——比如 upstream 超时未设、proxy_buffering off 导致响应阻塞、或客户端网络异常。











