worker_shutdown_timeout 是 Nginx 1.19.10+ 强制启用的超时机制,用于限制旧 worker 进程在 reload 后等待连接自然关闭的最大时长,超时后强制终止以防止资源滞留;必须置于 main 块,单位支持秒/分钟,合理取值需匹配业务最长连接生命周期。

worker_shutdown_timeout 是 Nginx 1.19.10+ 引入的硬性控制开关,不是可选项,而是生产中防止旧 worker 长期卡在 shutting down 状态的核心手段。它不解决“要不要 reload”,而是决定 reload 后旧进程能“体面退场”多久——超时前尽力服务完,超时后强制清理,避免资源滞留、连接异常中断和监控误报。
为什么旧 worker 会一直卡着不退出?
默认情况下,Nginx 不设超时:旧 worker 收到 QUIT 信号后,仅关闭监听套接字(不再接新连接),但会无限等待所有已建立连接自然结束。这对短连接影响小,但对以下场景极其危险:
- WebSocket 连接由客户端维持心跳,可能存活数小时
- HTTP/2 流式响应或 SSE 推送未完成
- 大文件上传中途、后端尚未返回 final response
- Keep-Alive 空闲连接处于默认 75 秒等待窗口内
结果就是 ps aux | grep "shutting down" 持续看到多个旧进程,内存持续占用,open socket left in connection 告警频发,甚至触发 OOM。
配置位置和写法必须准确
该指令只能出现在 main 块(即 nginx.conf 最外层,位于 events/http 之前),写错位置将完全失效:
✘ 错误示例(events 或 http 内):events {
worker_connections 1024;
worker_shutdown_timeout 30s; }
worker_shutdown_timeout 90s;
events {
worker_connections 1024;
}
http { ... }
单位支持秒(30s)、分钟(2m),不支持毫秒;设为 0 表示禁用机制,退回到传统快速退出。
怎么定一个靠谱的值?看业务,不拍脑袋
数值不是越长越好,需覆盖你最长的“合理活跃连接生命周期”,同时兼顾资源释放节奏:
- 纯 API 服务(短连接为主):设
15s—— 覆盖 P99 响应 + 网络抖动余量 - 含 Keep-Alive 和中等上传(如头像/文档):推荐
60s~90s—— 匹配浏览器 keepalive 默认窗口与常见上传耗时 - WebSocket / gRPC / HTTP/2 流:至少
3m,生产建议5m—— 给心跳、重连、服务端缓冲留足空间 - K8s Ingress Nginx 场景:起步
3m,并同步调大proxy_read_timeout和upstream keepalive_timeout,保持超时链路收敛
配合验证,别只靠猜
配置后务必实测是否生效,最简单方式:
- 在 server 块加一个模拟长响应 location:
location /delay { return 200 "done\n"; add_header X-Worker-Pid $pid; } - 用
curl -v http://your.domain/delay发起请求,同时执行nginx -s reload - 观察响应是否完整返回(而非 connection reset / timeout);检查响应头中的
X-Worker-Pid是否来自旧进程
再结合 error.log 查看是否有 worker process is shutting down 日志,并记录其从出现到消失的时长,用于后续微调。










