worker_shutdown_timeout 是为热重启时安全终止长连接 worker 进程设置的超时值,防止 WebSocket 场景下旧 worker 滞留导致内存堆积或 OOM;需置于 main 块,配合 proxy_http_version 1.1 等升级头配置方可生效。

设置 worker_shutdown_timeout 不是为了“避免重启”,而是为了让热重启(nginx -s reload)过程中,那些仍在处理 WebSocket 等长连接的 worker 进程,在合理时间内退出,防止内存持续堆积、进程滞留、甚至 OOM。
为什么 WebSocket 场景下必须关注这个指令
WebSocket 是全双工、长生命周期的 TCP 连接,不依赖 HTTP 请求-响应周期。Nginx 的旧 worker 在 reload 后进入 shutting down 状态,会继续服务这些连接,直到客户端主动断开或网络异常中断——这个过程可能长达数小时。若频繁 reload(如灰度发布、配置试调),大量 shutting down worker 会并存,每个占用几十至上百 MB 内存,极易触发系统资源告警或服务抖动。
默认情况下,Nginx 不设超时,worker 会无限等待连接自然结束。而 worker_shutdown_timeout 就是给这个“等待”加一道安全阀。
如何正确配置和生效
该指令必须放在 main 上下文(即 nginx.conf 最外层),不能写在 http/server/location 块内:
worker_shutdown_timeout 30s;
- 单位支持
s(秒)、m(分)、h(小时),例如1m、5m、1h - 值不宜过短:需大于业务中绝大多数 WebSocket 连接的空闲心跳间隔 + 网络往返时间,否则可能在心跳间隙被强制断连
- 推荐起始值:30s~2m;生产环境建议结合监控(如
nginx_stub_status中 Active connections 变化趋势)逐步调优 - 配置后必须执行
nginx -t && nginx -s reload才能生效,仅重载配置不重启进程即可
配合 WebSocket 代理的关键配套配置
单设 worker_shutdown_timeout 不足以保障 WebSocket 平滑,还需确保反向代理行为本身支持协议升级:
-
proxy_http_version 1.1;—— 必须启用 HTTP/1.1(HTTP/1.0 不支持 Upgrade) -
proxy_set_header Upgrade $http_upgrade;—— 透传客户端 Upgrade 请求头 -
proxy_set_header Connection "upgrade";—— 显式声明连接升级,注意引号不可省略 - 可选但强烈建议:
proxy_read_timeout 86400;—— 避免 Nginx 主动关闭空闲 WebSocket 连接(默认 60s)
缺少任一上述三项,WebSocket 连接会在首次 reload 后立即降级为 HTTP 短连接,导致前端报错 WebSocket is closed before the connection is established。
验证是否真正起效
执行 reload 后,通过以下方式确认行为符合预期:
- 观察日志:
tail -f /var/log/nginx/error.log中出现worker process is shutting down,且约worker_shutdown_timeout时间后对应 PID 消失 - 检查进程:
ps aux | grep 'nginx: worker process' | grep 'shutting down',数量应随时间递减,而非长期稳定存在 - 模拟长连接测试:用
wscat或浏览器建立 WebSocket 连接,reload Nginx 后确认连接未断、消息仍可双向收发,且约设定超时后旧 worker 正常退出
不复杂但容易忽略


















