worker_shutdown_timeout 是 nginx reload 时限制旧 worker 处理长连接的强制退出时限,必须配置在 main 块,值需覆盖业务最长耗时,并与 proxy_read_timeout 等协同对齐,超时后强制关闭 socket 退出。

worker_shutdown_timeout 不是用来“保活”旧连接的,而是给旧 worker 进程一个明确的退出时限——让它在 reload 时有足够时间处理完手头的 HTTPS 长连接(如 HTTP/2 流、Keep-Alive 空闲连接、大文件下载),但又不至于无限挂起。它不接管连接、不迁移请求、不干预协议语义,只决定“等多久就强制收工”。
必须放对位置:只在 main 块生效
这个指令不是可选配置,也不是放在 events 或 http 里就能用。它必须写在 nginx.conf 最外层的全局上下文(main 块)中,否则完全不生效:
- ✅ 正确写法:
worker_processes 4;<br>worker_shutdown_timeout 60s;
- ❌ 错误写法:
写在events { ... }或http { ... }内部 → 被忽略
写在server或location块里 → 语法错误或静默失效
值怎么设:看 HTTPS 连接的实际行为,不是拍脑袋
HTTPS 本身不改变机制,但 TLS 握手后的长连接类型决定了 timeout 应该覆盖什么:
- HTTP/2 多路复用连接:单个 TCP 连接承载多个请求流,生命周期由客户端/后端共同维持。若业务心跳间隔为 30s,网络 RTT ≤100ms,建议设为 90s(留出 2 倍缓冲)
- 启用了 TLS Session Resumption + Keep-Alive 的 HTTPS/1.1:空闲连接默认可能保持 5–75 秒。设为 30s~60s 可覆盖绝大多数自然关闭窗口
- 大文件下载或上传(如 PDF、视频流):需匹配最大传输耗时。例如带宽受限下 500MB 文件上传需约 200 秒,则 worker_shutdown_timeout 至少设为 240s,同时确保
client_body_timeout和proxy_send_timeout≥ 此值 - 反向代理到 gRPC 或后端慢服务:以该链路 P99 耗时为基准,加 30% 余量。比如后端响应 P99 是 48 秒,设为 65s
单靠它不够:必须协同 proxy 和 client 超时参数
worker_shutdown_timeout 是“倒计时终点”,但在此之前,其他超时设置可能提前掐断连接:
-
proxy_read_timeout和proxy_send_timeout必须 ≥worker_shutdown_timeout:否则 Nginx 可能在倒计时结束前,就因后端响应慢而主动关闭 upstream 连接,导致客户端收到 RST -
client_header_timeout和client_body_timeout应 ≤worker_shutdown_timeout:避免客户端迟迟不发完请求头或 body,却卡住旧 worker 直到 shutdown 超时才退出 -
keepalive_timeout可独立设(如 600s),它管的是空闲复用连接;而worker_shutdown_timeout管的是 reload 期间所有活跃连接的总存活上限——两者职责不同,可共存
验证是否真起作用:别只看进程列表
光看 ps aux | grep nginx 发现旧 worker 消失了,不代表连接被完整处理。更可靠的验证方式:
- 部署一个真实延迟响应接口(如
location /delay { echo_sleep 45; return 200 "done"; }),在 reload 同时发起 HTTPS 请求,确认返回成功而非 502/timeout - 开启
error_log /var/log/nginx/error.log debug;(仅测试环境),reload 后查日志是否有类似worker process [xxx] exited on signal 15 after 45.234 sec的记录 - 用
ss -tnp | grep :443观察 reload 前后 ESTABLISHED 连接数变化趋势:应缓慢下降(自然关闭),而非瞬间归零(强制中断)
本质上,worker_shutdown_timeout 是热重载时的“安全阀”,不是万能胶。它让旧 worker 退得干净、不拖泥带水,但真正的平滑,还得靠上下游配合和合理的时间窗口设计。











