nginx 平滑重载需 systemd 配置对齐:启用 --with-systemd 编译、设 type=notify、execreloadpre 校验配置、execreload 指定命令,并用健康检查验证生效,reload 不中断连接,restart 才中断。

用 systemd 管理 Nginx 的平滑重载与重启,关键不是“能 reload”,而是让 reload 真正可靠、可验证、不误判。systemd 本身不理解 Nginx 的平滑语义,必须靠配置对齐其进程模型和信号行为。
确保 Nginx 编译支持 systemd 原生通知
平滑操作的底层稳定性依赖于 Nginx 主进程能否主动告知 systemd 自身状态变化。检查是否启用:
- 运行
nginx -V 2>&1 | grep -o 'systemd',输出 systemd 表示已开启 - 若无输出,需重新编译 Nginx,添加
--with-systemd参数 - 启用后,推荐在 service 文件中设
Type=notify(要求 Nginx ≥ 1.19.10),比Type=forking更精准识别“重载完成”
service 文件中正确声明 reload 行为
systemd 默认的 systemctl reload nginx 仅发送 SIGHUP,但若未明确定义,可能跳过配置校验或忽略失败。需在 /etc/systemd/system/nginx.service 的 [Service] 段补充:
-
ExecReload=/usr/sbin/nginx -s reload:显式指定 reload 命令路径(按实际安装位置调整) -
ExecReloadPre=/usr/sbin/nginx -t -c /etc/nginx/nginx.conf:每次 reload 前强制校验语法,失败则中止,不触发信号 - 若使用
Type=notify,Nginx 重载完成后会发 READY=1,systemd 才认为 reload 成功;否则可能返回 “reloading” 却卡住
配合健康检查验证 reload 真实生效
reload 命令返回成功 ≠ 新配置已处理请求。master 进程收到 SIGHUP 后可能卡在 worker 启动阶段,或新 worker 因配置错误无法 accept 连接——此时 systemd 仍显示 active。建议:
- 在
nginx.conf中加探针:location /healthz { return 200 'OK'; add_header Content-Type text/plain; } - 写一个 reload 后验证脚本(如
/usr/local/bin/wait-nginx-reload.sh):systemctl reload nginx && until curl -f http://127.0.0.1/healthz >/dev/null 2>&1; do sleep 0.5; done - 将该脚本集成进 CI/CD 或运维流程,避免“以为 reload 完了,其实没生效”
区分 restart 与 reload 的实际效果
别混淆两个命令的语义和后果:
-
systemctl reload nginx→ 发送 SIGHUP → 主进程重读配置、启动新 worker、旧 worker 优雅退出 → 连接不中断 -
systemctl restart nginx→ 先 stop(SIGTERM + 等待超时)再 start → 必然中断连接,仅用于配置变更涉及 master 行为(如 user、pid 路径)或 worker 无法热更的场景 - 日常配置更新(server、location、proxy_pass 等)一律用
reload,不要用restart











