nginx -s reload 是 master 进程驱动的受控进程交接:先语法校验,再 fork 新 worker 并发 quit 信号,旧 worker 优雅处理存量请求,新旧共存直至自然退出,全程不中断服务。

零停机重启不是靠“重启”实现的,而是靠 master 进程调度 + worker 进程更替完成的。整个过程不关闭监听端口、不中断已有连接、不丢弃正在处理的请求。
配置热重载的核心机制
执行 nginx -s reload 或向 master 发送 SIGHUP 信号后,并非重启服务,而是触发一次受控的进程交接:
- master 进程重新读取并校验 nginx.conf(含所有 include 文件),语法错误会直接报错,新 worker 不启动,旧 worker 继续运行
- 校验成功后,master 基于新配置 fork 出一批新 worker 进程
- 同时向旧 worker 发送 QUIT 信号,它们不再接受新连接,但继续处理完所有存量请求(包括长连接、上传中文件等)
- 新旧 worker 可能共存数秒至数分钟,直到旧 worker 自行退出
为什么不会中断服务
关键在于职责分离与资源继承:
- 监听套接字始终由 master 持有并统一分发,新旧 worker 共享同一组 listen socket,客户端无感知
- worker 启动时继承的是 master 已解析好的内存配置结构,运行期间配置只读,不存在运行时修改或锁竞争
- 配置文件替换使用 mv 原子操作(如 mv nginx.conf.new nginx.conf),worker 从不直接读配置文件,避免读到中间状态
必须做好的三件事
跳过任一环节都可能导致“假成功”或服务异常:
- 先执行 nginx -t -c /path/to/nginx.conf:验证语法、路径、权限(如 SSL 证书可读、日志目录可写)、include 子文件是否存在
- 确认 worker_shutdown_timeout 设置合理:默认 10 秒,若存在大文件上传或长轮询,建议设为 30–60 秒,确保旧 worker 有足够时间收尾
- 区分配置变更与二进制升级:reload 只更新配置;若要升级 nginx 本身,需用 USR2/WINCH/QUIT 三步信号,且需检查 ABI 兼容性
如何确认生效而非“假成功”
不能只看命令返回 OK 或 ps 显示进程在跑:
- 查新 worker 启动时间:
ps -eo pid,comm,lstart | grep 'worker process',对比 reload 时间戳 - 测关键配置项:
curl -I http://localhost | grep X-Your-Custom-Header,确认响应头已按新配置输出 - 观察 error.log:若 reload 失败,master 会记录 emerg 级错误,但进程仍在运行,极易被忽略











