worker_shutdown_timeout 是旧 worker 优雅退出的超时限制,仅控制其最长等待时间并强制终止未关闭连接,不支持也不实现连接强制平移或流量切换。

worker_shutdown_timeout 本身不支持“强制平移”,它也不是为“强制切换流量”设计的机制。这个词在 Nginx 官方文档和工程实践中并不存在——你可能混淆了概念:它既不强制迁移连接,也不主动把请求从旧 worker “平移”到新 worker,更不会干预连接归属或路由决策。
它只做一件事:
给正在优雅退出的旧 worker 进程,设一个最长等待时间,超时后强制终止其所有未自然关闭的连接。
它真正能做的:控制旧进程“退场节奏”
当执行 nginx -s reload 时:
- Master 启动新 worker,开始接受新连接
- 同时向旧 worker 发送
QUIT信号,它们立刻停止accept()新连接 - 但继续服务已建立的连接(HTTP 请求、keepalive 空闲连接、WebSocket TCP 流、上传中段等)
- 此时
worker_shutdown_timeout开始倒计时
✅ 它保障的是“不中断已有工作”:让旧 worker 把手头活干完再走
❌ 它不实现“强制平移”:Nginx 不会把一个正在传输的 WebSocket 帧、一个未结束的 HTTP/2 stream、或一个大文件上传,从旧 worker “搬”到新 worker 上
为什么不能“平滑强制平移”?
- Nginx 的 worker 是相互隔离的进程,不共享连接句柄或内存上下文
- TCP 连接绑定在特定 worker 的 epoll/kqueue 实例上,无法跨进程移交
- WebSocket / HTTP/2 / SSE 等长连接是端到端状态化通道,服务端无协议级“移交”能力
- 所谓“平滑”,本质是:旧连接自然结束 + 新连接由新 worker 接管,而非“搬运”
想接近“强制平移效果”?靠组合策略,不是单靠这个参数
| 目标 | 关键手段 | 说明 |
|---|---|---|
| 减少旧连接滞留 | 设合理 worker_shutdown_timeout(如 90s) |
防止旧 worker 卡住几小时;值需 ≥ 业务最长心跳间隔 + RTT + 缓冲 |
| 让新连接不打到旧 worker | Nginx upstream 健康检查 + proxy_next_upstream error timeout http_503
|
后端主动返回 503,Nginx 自动摘流,新请求全发给新 worker |
| 客户端无缝续连 | 客户端实现指数退避重连 + 消息幂等 + 连接 ID 绑定 | 断连后快速重建,且不重复处理 |
| 避免 Nginx 主动断连 |
proxy_read_timeout 86400; keepalive_timeout 600s;
|
别让 Nginx 自己先 kill 掉长连接 |
配置要点(务必注意)
- ✅ 只能写在
main块(nginx.conf最外层),例如:worker_shutdown_timeout 90s;
- ❌ 写在
http、server、location或events块内完全无效 - ⚠️ 单位支持
s/m/h(如2m、1h),不设则无限等待 - ⚠️ 它不影响新 worker 启动,也不参与配置校验或加载逻辑
总结一句话
worker_shutdown_timeout 是一道“安全闸门”,防止旧 worker 在 reload 后无限期挂起;它让退出变得可预期、可收敛、不堆积资源,但绝不是连接迁移开关。真正的平滑,靠的是协议透传正确、超时设置合理、后端配合摘流、客户端健壮重连——它只是其中一环,而且是收尾的一环。










