worker_shutdown_timeout 是保障 WebSocket 平滑重载的关键,须置于 main 块、值≥心跳间隔+RTT并留余量,且必须配合 proxy_http_version 1.1、Upgrade/Connection 头透传及客户端重连策略。

要让缓存刷新重载(nginx -s reload)时 WebSocket 连接不被粗暴中断,worker_shutdown_timeout 是关键一环,但它本身不能单独“保障平滑”,必须配合协议升级、超时控制和客户端协同才能真正落地。
必须放在 main 块,且值要匹配业务心跳周期
该指令只在 Nginx 主配置上下文(即 nginx.conf 最外层)生效,写在 http、server 或 location 中无效:
- 正确写法:
worker_shutdown_timeout 90s;(推荐起始值:60s~120s) - 值不能小于 WebSocket 心跳间隔 + 网络往返时间,否则可能在心跳空档期被强制终止
- 若后端心跳为 30 秒、客户端网络延迟普遍在 200ms 内,设为 45s 就偏紧;建议留出 2 倍余量,如设为 90s 更稳妥
仅设 timeout 不够,必须配套 WebSocket 代理头
Nginx 不解析 WebSocket 帧,能否维持连接完全取决于 HTTP 升级是否成功透传。缺一不可:
WebSocket 8.18.2 是该协议规范的一个重要迭代版本,主要优化了连接稳定性与数据传输效率。它通过全双工通信机制,允许客户端与服务器在单一长连接上实时交换数据,大幅降低传统 HTTP 轮询的开销。该版本增强了心跳保活、自动重连及二进制帧传输能力,适用于即时通讯、在线游戏及金融行情推送等低延迟场景,为开发者提供更可靠的实时网络交互基础。
-
proxy_http_version 1.1;—— HTTP/1.0 不支持 Upgrade,必须启用 1.1 -
proxy_set_header Upgrade $http_upgrade;—— 透传客户端原始 Upgrade 头 -
proxy_set_header Connection "upgrade";—— 注意英文双引号不能省略 - 可选但强烈建议:
proxy_read_timeout 86400;避免 Nginx 默认 60 秒主动断连空闲连接
reload 前需验证并避免手动 kill shutdown 进程
即使配置正确,操作不当也会引发异常断连和 socket 泄漏:
- 每次修改后必须执行
nginx -t验证语法,再nginx -s reload - 看到 worker 处于
shutting down状态是正常中间态,不要用kill或kill -9强制终止 - 强制 kill 会导致
open socket left in connection日志告警,连接无法 clean up - 若发现大量 shutdown 进程长期滞留,优先检查后端是否未响应、客户端心跳是否失效,而非调小 timeout
更可靠的平滑路径:服务端主动 draining + 客户端重连策略
因为 Nginx 层面对 WebSocket 实质上是 TCP 透传,真正可控的平滑依赖三方配合:
- 后端提供健康检查端点(如
/healthz),下线前返回 503,Nginx 可结合proxy_next_upstream error timeout http_503自动摘流 - 客户端实现指数退避重连(如首次 1s,失败后 2s、4s、8s…),避免重连风暴
- Kubernetes 场景下,用 Ingress Nginx Controller 的滚动更新 +
terminationGracePeriodSeconds配合连接 draining - 运维侧可先 reload,观察
nginx_stub_status中 Active connections 缓慢下降趋势,确认旧连接自然退出后再推进下一步










