nginx平滑重载靠master与worker分工协作实现:master校验新配置后拉起新worker并通知旧worker优雅退出,确保不丢请求。需注意配置路径、权限、端口冲突等要点,并排查pid、缓存、time_wait等问题。

当 Nginx 运行时,无需停止服务即可更新配置并生效,靠的是 Master 进程与 Worker 进程的分工协作机制。核心在于:Master 进程负责读取、校验新配置,并通知旧 Worker 优雅退出,同时拉起新 Worker 承接流量——整个过程对客户端请求无感知。
Master 进程如何触发重载
执行 nginx -s reload 或 kill -s HUP
- 重新解析 nginx.conf 及所有 include 的配置文件
- 进行语法检查和配置项合法性验证(如端口冲突、路径不可写等)
- 若校验失败,Master 继续运行旧配置,日志中记录错误,不中断服务
- 若校验通过,则 fork 新 Worker 进程,使用新配置初始化;同时向旧 Worker 发送 QUIT 信号
Worker 进程的优雅退出机制
收到 QUIT 信号后,旧 Worker 并不立即终止,而是:
- 停止接受新连接,但继续处理已建立的连接和未完成的请求
- 等待所有活跃请求结束(包括长连接、上传中、后端响应未返回等情况)
- 超时(默认 worker_shutdown_timeout 为关闭状态,实际依赖 worker_connections 和业务响应时间)或全部请求完成后自行退出
这个“不丢请求”的特性,是实现平滑重载的关键保障。
确保重载真正生效的几个要点
- 配置路径必须正确:使用 nginx -t 预检,确认配置语法和文件路径有效(尤其注意 root、ssl_certificate 等涉及磁盘路径的指令)
- 权限不能丢失:新 Worker 启动时仍以 user 指令指定的用户身份运行,确保其对日志目录、SSL 证书、proxy_temp_path 等有读写权限
- 避免热重载中的配置陷阱:例如修改了 listen 端口但未释放原端口,或 upstream 加了新 server 却忘了健康检查配置,可能导致部分请求异常
- 观察进程变化:用 ps aux | grep nginx 可看到新旧 Worker 并存一段时间;nginx -s reload 后 Master 进程 PID 不变,Worker PID 全部刷新
常见问题与应对
重载失败通常表现为:
- 执行 nginx -s reload 后无响应、报错或提示 “nginx: [error] invalid PID number” —— 多因 nginx.pid 路径不对或权限不足,检查 pid 指令配置及 /var/run/nginx.pid 所在目录可写性
- 配置已更新但请求仍走旧逻辑 —— 很可能是浏览器缓存了 301/302、CDN 缓存未刷新,或 upstream server 自身有状态未同步
- 大量 TIME_WAIT 连接堆积 —— 重载频繁或 worker_shutdown_timeout 过短导致旧连接来不及释放,建议合理设置 keepalive_timeout 和系统 net.ipv4.tcp_fin_timeout










