worker_shutdown_timeout必须置于main块,按业务设15–30s(rest)、45–90s(长轮询)、90–300s(websocket)、≥450s(大上传),并确保proxy_read/send_timeout≥其值、client_header/body_timeout≤其值,websocket还需配齐upgrade头。

要让 Nginx 平滑重载(nginx -s reload)时旧 worker 进程真正优雅退出,核心不是“等它自己走完”,而是用 worker_shutdown_timeout 主动设限,并配合上下游超时闭环控制。
必须把 worker_shutdown_timeout 放在 main 块
这个指令只在全局上下文生效,写错位置等于没配:
- ✅ 正确:直接写在
nginx.conf最开头,和其他全局配置(如user、worker_processes)同级 - ❌ 错误:放在
http、events、server或location块里——Nginx 会静默忽略
根据业务类型设合理超时值
它不决定新连接行为,只约束旧 worker 处理已有连接的最长时间。参考典型场景:
- 普通 REST API(P99 ≤ 1s):15–30s 足够覆盖抖动和慢查询
- Keep-Alive / 长轮询(空闲超时通常 5–75s):45–90s,略大于
keepalive_timeout - WebSocket / SSE / HTTP/2 流:至少 90s~300s;若心跳间隔为 30s,建议 ≥ 90s
- 大文件上传(如 200MB @ 512KB/s ≈ 400s):设为 450s 起,并同步确认
client_body_timeout≥ 450
必须协同配置上下游超时
单设 worker_shutdown_timeout 没用,它只是“终点线”,其他超时才是“跑道”:
-
proxy_read_timeout和proxy_send_timeout必须 ≥worker_shutdown_timeout,否则反向代理会在后端响应前主动断连 -
client_header_timeout和client_body_timeout应 ≤worker_shutdown_timeout,防止客户端迟迟不发完请求头或体,卡住旧 worker - WebSocket 场景还需三件套:
proxy_http_version 1.1、proxy_set_header Upgrade $http_upgrade、proxy_set_header Connection "upgrade"
验证是否真起作用
别只看进程是否消失,重点观察连接行为:
- 加一个延时测试接口:
location /slow { return 200 "done after 25s\n"; } - 执行
nginx -s reload同时发起curl http://host/slow - 成功返回且无中断,说明 timeout 已生效;若报错或超时,检查位置、单位、配套超时是否对齐
- 查日志:
/var/log/nginx/error.log中应有exiting和exit记录











