Nginx平滑重载的核心是master进程接收SIGHUP后校验配置、fork新worker、通知旧worker优雅退出,全程不中断服务、不丢请求。

Linux 下 Nginx 平滑重载(nginx -s reload)的底层核心,就是 master 进程接收并处理 SIGHUP 信号,整个过程不重启服务、不中断连接,靠的是进程协作与信号驱动的原子切换。
master 收到 SIGHUP 后做了三件事
当执行 nginx -s reload 或手动 kill -HUP $(cat /var/run/nginx.pid) 时,信号只发给 master 进程。它立刻开始以下动作:
-
校验新配置:重新读取
nginx.conf及所有 include 文件,检查语法和路径有效性;任一错误就中止,旧配置继续运行,不会影响服务 - fork 新 worker:校验通过后,master 基于新配置 fork 出一批全新 worker 进程;这些新 worker 拥有独立内存空间和只读配置副本,立即开始监听同一端口(依靠内核 SO_REUSEPORT 或继承 socket fd 实现)
-
通知旧 worker 优雅退出:master 向每个旧 worker 发送
QUIT信号;旧 worker 不再 accept 新连接,但会持续处理已建立的请求(包括长连接、上传中、Keep-Alive 等),直到全部完成才自行退出
为什么用户感觉不到切换?
关键在于新旧 worker 是并行存在的短暂窗口期:
Linux 性能分析与调优专家,覆盖 CPU、内存、磁盘 I/O、网络、内核参数、编译优化、容器/K8s。适用场景:系统卡顿/高负载、内存不足/OOM/Swap 高、CPU 异常/iowait 高。
- 新 worker 接管所有新进连接,响应速度由新配置决定
- 旧 worker 继续服务尚未结束的连接,比如一个正在传输大文件的下载请求,或一个 WebSocket 长连接
- 没有共享内存、没有配置热写入、没有锁竞争——切换是无状态的,靠进程自然消亡完成过渡
常见误区:reload ≠ restart
很多人误以为 reload 就是“重启 nginx”,其实它完全不涉及 stop + start 流程:
-
restart(如
systemctl restart nginx)会先发 TERM 给 master,强制终止全部进程,再重新拉起;中间存在毫秒级甚至秒级的服务空白 - reload 全程 master 一直存活,worker 进程组平滑轮换;只要旧 worker 还在处理请求,服务就始终可用
- 如果配置改错,reload 失败,master 会原样保留旧 worker,业务零影响——这也是它比 restart 更安全的根本原因
怎么确认重载是否真正生效?
不能只看命令没报错,要验证实际行为:
- 查进程:
ps aux | grep nginx—— 应同时看到旧 worker(PPID 是老 master)和新 worker(PPID 是同一 master,但启动时间更新) - 看日志:
tail -f /var/log/nginx/error.log—— 成功 reload 会有reloading configuration记录;失败则明确提示哪一行出错 - 测效果:修改一个 location 规则后,用
curl -I或浏览器开发者工具观察响应头、状态码或后端转发路径是否变化

















