worker_shutdown_timeout 是防止旧 worker 卡在 shutting down 的关键配置,必须置于 main 块,值需匹配最长连接生命周期并协同 proxy/client 超时设置;错误位置将被静默忽略,单独配置无效,须闭环上下游超时参数。

要让 Nginx 平滑重载(nginx -s reload)时旧 worker 进程不卡在 shutting down 状态,关键不是“等它自己走完”,而是用 worker_shutdown_timeout 给它设一道明确的退出时限——超时即退,不拖不挂。
必须放在 main 块,否则完全无效
这个指令只在全局上下文生效,也就是 nginx.conf 最外层、events 和 http 块之前的位置:
- ✅ 正确写法:
worker_processes 4;
worker_shutdown_timeout 90s;
(和其他顶层配置如user、pid同级) - ❌ 错误写法:
http { worker_shutdown_timeout 60s; }或events { worker_shutdown_timeout 30s; }
Nginx 会静默忽略,日志里也看不到报错
值怎么定:按业务连接类型反推
它不控制新连接,只决定旧 worker 最多陪已有连接走多久。设短了断连,设长了堆积:
- 普通 REST API(P99 ≤ 1s):15–30s,覆盖抖动和慢查询
- Keep-Alive / 长轮询(空闲超时通常 5–75s):45–90s,建议略大于
keepalive_timeout - WebSocket / SSE / HTTP/2 流:至少 90s~300s;若心跳 30s,起步设 90s(≥ 心跳 × 2 + RTT)
- 大文件上传(如 200MB @ 512KB/s ≈ 400s):至少设为 450s,并同步确认
client_body_timeout ≥ 450
单设它没用,必须闭环上下游超时
worker_shutdown_timeout 只是倒计时终点,其他超时参数可能提前掐断连接:
-
proxy_read_timeout和proxy_send_timeout必须 ≥ 它的值
否则 Nginx 会在后端响应完成前主动关 upstream 连接,导致客户端收到 RST -
client_header_timeout和client_body_timeout应 ≤ 它的值
防止慢客户端迟迟不发完头或体,把旧 worker 卡死在读阶段 - WebSocket 场景还必须配齐三件套:
proxy_http_version 1.1;proxy_set_header Upgrade $http_upgrade;proxy_set_header Connection "upgrade";
验证是否真起作用
别只看语法检查通过,要实测:
- 在
server块中加一个延时响应测试 location:location /slow { return 200 "done after 25s\n"; } - 执行
nginx -s reload的同时,立刻用curl http://yourhost/slow发起请求 - 如果完整返回且无中断,说明 timeout 已生效;如果超时或报错,重点检查位置、单位、配套超时是否匹配











