systemd 本身不支持“一键平滑重启整个集群”,真正的平滑需上层编排(如Ansible/Consul)+服务自身支持reload(如nginx/haproxy)+外部健康检查与滚动控制共同实现。

一、单节点层面:用 reload 或可控 restart 替代暴力重启
不是所有服务都支持 reload,但关键中间件(Nginx、HAProxy、Redis、rsyslog 等)通常支持 SIGHUP 平滑重载配置,不中断连接:
-
优先尝试 reload:对支持的服务执行
systemctl reload nginx、systemctl reload haproxy,零中断生效新配置 -
MySQL / PostgreSQL 不支持 reload:必须 restart,但可控制节奏——先设
innodb_fast_shutdown = 0(MySQL 8.0.22+),再mysqladmin shutdown,缩短刷盘时间 -
避免无条件 restart:用
systemctl try-restart mysqld,仅对正在运行的节点操作,跳过已停机或故障节点,防止误启
二、集群层面:靠外部协调实现“滚动”而非“同时”
systemctl 本身不跨机器,需借助工具串联节点操作。常见可靠组合:
-
Ansible + health check + delay:每个节点执行前,先调用 API 或 curl 检查上游负载均衡器是否已摘除该节点;摘除成功后,再执行本地
try-restart;完成后等待几秒,再恢复节点注册 -
Consul + systemctl + reload-or-restart:服务注册到 Consul 后,通过
consul watch监听 KV 变更,触发本地systemctl reload-or-restart nginx(若支持 reload 则 reload,否则 fallback 到 restart) -
自建状态门控脚本:例如在重启前执行
curl -sf http://localhost:8080/health | grep -q "ready",失败则 sleep 重试或退出,避免带病重启
三、服务单元层面:让 systemd 协助“优雅收尾”
修改服务单元文件(如 /etc/systemd/system/mysqld.service),增强可控性:
- 添加
ExecStop=/usr/bin/mysqladmin --socket=/var/lib/mysql/mysql.sock shutdown,替代默认 kill - 设置
TimeoutStopSec=60,给 InnoDB 足够刷脏页时间 - 启用
Restart=on-failure和RestartSec=5,确保异常崩溃后自动恢复,减少人工干预 - 若服务支持 socket 激活(如某些 Go 服务),使用
.socket单元 +Accept=false,可实现新旧进程共存过渡


















