Nginx优雅退出是主从进程协作的状态驱动流程:主进程收SIGQUIT后关监听、经channel socket发QUIT指令;worker设ngx_exiting=1、停接入、清空闲连接、处理完活跃请求后退出,超时由worker_shutdown_timeout兜底。

Nginx 的优雅退出不是靠“杀掉进程”实现的,而是主进程和 worker 进程协作完成的一套状态驱动流程。核心在于:不中断正在处理的请求,等它们自然结束或超时后才退出。
主进程触发退出:收 SIGQUIT,关监听,发指令
当执行 nginx -s quit 或 kill -QUIT $(cat nginx.pid) 时:
- 主进程收到 SIGQUIT 信号,立即关闭所有监听套接字(不再 accept 新连接)
- 通过已建立的 channel socket(Unix domain socket),向每个 worker 进程发送 QUIT 指令——这不是系统信号,而是 Nginx 自定义的内部指令
- 主进程开始等待 worker 退出;若超过默认 10 秒仍未完成,则强制终止(SIGKILL)
worker 进程响应:设标志、停接入、清空闲、处理完再退
worker 不响应系统信号,而是轮询主进程发来的指令:
- 收到 QUIT 指令后,设置内部标志 ngx_exiting = 1
- 关闭监听套接字(已建立的连接仍可读写)
- 主动关闭空闲 keepalive 连接(如 HTTP/1.1 长连接池中的闲置连接)
- 继续处理已入队的请求、定时器、事件和活跃连接上的数据收发
防止卡死:worker_shutdown_timeout 是关键兜底
某些场景下连接无法自然关闭(如慢后端、WebSocket 空闲、TCP 代理未断连),worker 可能一直不退出:
- 在 http 或 stream 块中配置:worker_shutdown_timeout 30s;
- 该值表示:从进入退出流程起,最多等待 30 秒;超时后,仍在处理的连接会被强制关闭,worker 随即退出
- 对纯 HTTP 请求效果最好;对 WebSocket、gRPC、TCP 代理等无请求边界的协议,这个超时是必要保障
验证是否真正优雅完成
不能只看进程是否消失,要结合日志与状态判断:
- 查看 /var/log/nginx/error.log:应出现 signal 3 (SIGQUIT) received, exiting 和 exit 日志
- 运行 ps aux | grep nginx:主进程退出,旧 worker 逐个消失,新 worker(如 reload 场景)应已就位
- 用 ss -tnp | grep :80 观察:监听 socket 应随主进程退出而消失
- 发起一个带 sleep 的长请求(如后端 sleep 10 秒),确认它能完整返回


















