nginx 平滑迁移依靠多进程模型与信号协作实现,主进程统一响应 sighup 解析新配置并 fork 新 worker,新旧 worker 并行处理请求,旧 worker 自然退出,全程无中断。

配置平滑迁移在 Nginx 中不是靠“热替换变量”实现的,而是依托多进程模型与信号协作,让新旧配置在不同 worker 进程中并行生效,用户请求始终有进程承接,全程无感知。
主进程统一接管 reload,杜绝配置竞争
所有配置变更(如执行 nginx -s reload)都由 master 进程集中响应。它收到 SIGHUP 信号后,才开始解析新配置文件;worker 进程完全不读磁盘,只运行 fork 时继承的内存副本——这意味着配置在 worker 生命周期内是只读且隔离的,天然避免多进程同时读写导致的不一致。
- master 在解析前会尝试原子创建锁文件(如
nginx.pid.lock),成功即获得排他操作权,防止并发 reload 冲突 - 锁文件仅作占位用,生命周期极短,不依赖系统级 flock,跨平台兼容性好
- 配置更新推荐先写临时文件(如
nginx.conf.new),再用mv原子替换,确保 worker 永远读到完整配置
新旧 worker 并行运行,连接分级退出
平滑的核心不是“切换”,而是“共存”。master 启动新 worker 后,新旧进程同时在线:
- 新 worker 立即开始 accept 新建连接,并按新配置处理请求(如新 upstream、新 rewrite 规则)
- 旧 worker 不再 accept 新连接,但继续处理已建立的连接——包括长连接、上传中请求、WebSocket 等
- 旧 worker 在完成当前请求、关闭空闲连接后自动退出,无需强制 kill,也不中断任何业务流
配置变更与二进制升级解耦,各自独立保障原子性
配置 reload 和 nginx 二进制升级(USR2)走的是两套互不干扰的路径:
- 配置 reload:只涉及 master 重新解析 + fork 新 worker,不改动二进制,不影响进程镜像
- 二进制升级:先替换
/usr/sbin/nginx文件,再发 USR2 信号;新 master 加载的是磁盘最新二进制,旧进程仍运行在原镜像上 - 二者都依赖 rename() 或文件替换等系统级原子操作,从根源规避半截状态
动态后端扩容也靠同一机制自然生效
upstream 节点增删、权重调整等变更,同样通过 reload 触发:
- 新 worker 启动后,直接使用含新节点的 upstream 列表进行负载均衡
- 旧 worker 继续按旧列表服务存量连接,直到自然退出
- 配合 readiness 探针,可确保新节点真正就绪后再被新 worker 选中,避免流量打到未准备好的实例











