Nginx平滑重载通过新旧worker并行运行与连接分级退出实现无中断过渡:master校验配置后fork新worker处理新连接,旧worker仅处理存量连接直至自然退出,全程原子替换配置、不共享内存、客户端无感。

Nginx 平滑重载不靠“切换”,而是让新旧 worker 进程并行运行一段时间,靠连接生命周期自然过渡。核心是 master 主导、worker 无感、配置只读、连接分级退出。
新旧 worker 同时在线,职责明确
收到 SIGHUP(如执行 nginx -s reload)后,master 进程完成配置校验,立即 fork 出一批新 worker 进程。此时:
- 新 worker 立即开始
accept()新建连接,并按新配置处理请求 - 旧 worker 不再 accept 新连接,但继续处理所有已建立的连接——包括 Keep-Alive 复用连接、正在上传的大文件、WebSocket 长连接、HTTP/2 流等
- 新旧 worker 彼此隔离,不共享内存或配置,互不影响
旧进程不是被杀掉,而是优雅退出
旧 worker 不会立刻终止,而是进入“服务收尾”状态:
- 不再响应新请求,也不打开新连接
- 持续处理当前请求直到完成(例如返回完整响应体、关闭 TCP 连接)
- 空闲连接在
keepalive_timeout后自动关闭 - 全部连接清理完毕后,进程自行退出,无需强制
kill
配置更新必须原子,避免读到中间态
worker 进程启动后只读取一次配置,因此配置变更必须“全有或全无”:
- 不要直接编辑线上
nginx.conf,应先写入临时文件(如nginx.conf.new) - 用
mv nginx.conf.new nginx.conf原子替换(底层是rename()系统调用,不可中断) - reload 时 master 总是读取最新 inode,而旧 worker 仍运行原副本,不会出现配置错乱
整个过程对客户端完全透明
用户感知不到任何变化:
- 监听 socket 由 master 持有并继承,端口始终可用
- 新连接落到新 worker,存量连接留在旧 worker,无请求丢失
- 健康检查、负载均衡器持续收到响应,不会触发节点摘除











