Nginx配置热重载本质是master驱动的五步进程交接:校验配置、开新端口、启新worker、发QUIT信号、旧worker优雅退出;期间新旧worker并存、内存双副本,服务不中断但非零成本。

Nginx 多进程模型通过 master-worker 分工与信号协作,实现配置热重载不中断服务。核心不是“替换配置”,而是“新旧进程并存、分阶段交接”。
master 进程全程驱动五步流程
reload 不是 worker 自行更新,而是由 master 统一调度:
- 收到 HUP 信号后,先执行 nginx -t 全量校验新配置(含所有 include 文件),语法错误则中止,旧配置照常运行
- 语法通过后,尝试打开新配置中新增的监听端口(如 8443 或 IPv6 地址),任一端口失败即回滚
- 用新配置 fork 出一批新 worker 进程,它们继承 master 已打开的所有监听 socket(包括旧端口和新端口)
- 向全部旧 worker 发送 QUIT 信号,要求其停止 accept 新连接,但继续处理已建立的请求(含长连接、WebSocket、大文件上传等)
- 旧 worker 完成所有活跃请求后,释放内存、关闭句柄、自行退出;master 最终清理旧配置结构体
新旧 worker 并存是关键设计
在 reload 完全完成前,系统必然同时运行两组 worker:
- 新 worker 立即开始 accept 新连接,内核通过 EPOLL/kqueue 将新连接自动分发过去
- 旧 worker 只处理存量连接,不接新请求,直到自然结束或超时退出
- worker 进程数临时翻倍,高并发下可能引发 CPU 缓存抖动或调度争抢
- 若旧连接耗时很长(如百 MB 文件上传未完成),会延迟内存释放和配置完全切换
内存波动源于配置结构体双副本
reload 中内存短暂上升不是故障,而是机制使然:
- master 解析新配置时,会构建一套完整的新结构体(含 server/location 树、缓存区、模块上下文等)
- 此时旧结构体仍在旧 worker 进程内存中驻留,新旧两套并存,内存使用接近翻倍
- 旧 worker 退出后,master 释放旧结构体,但 glibc 堆内存未必立即归还操作系统,top 中 RES 值回落较慢属正常
- 启用 proxy_cache、增大 client_max_body_size、加载大型第三方模块(如 subs_filter)、配置大量 server 块,都会显著放大该波动
不升级版本,只更新配置
nginx -s reload 本质是配置热更新,不是二进制升级:
- 它不会启动新 master 进程,也不替换 nginx 二进制文件
- 所有变更仅限于配置文件语义层面:监听地址、缓存策略、超时设置、路由规则等
- 若需升级 Nginx 版本,必须使用 平滑二进制升级(kill -USR2 + kill -WINCH + kill -QUIT),那是另一套机制


















