systemd服务自动重启未恢复业务因restart=on-failure不检查实际健康状态;应配合execstartpost健康检查、restartpreventexitstatus防死循环及startlimit限制防雪崩。

为什么 systemd 服务自动重启后没真正恢复业务?
因为 Restart=on-failure 只看进程退出码,不检查端口是否监听、API 是否可响应。服务进程起来了,但数据库连不上、配置加载失败、依赖服务没就绪——systemd 完全不管。
实操建议:
- 用
ExecStartPost=调用轻量健康检查脚本,比如curl -sf http://localhost:8080/health | grep ok,失败则kill $MAINPID - 在
[Service]段加RestartPreventExitStatus=255,让健康检查失败时退出码 255 不触发重启,避免死循环 - 别依赖
RestartSec=硬等时间,改用StartLimitIntervalSec=+StartLimitBurst=控制单位时间最大尝试次数,防雪崩
prometheus 抓不到节点指标?先查 node_exporter 的 --no-collector. 参数
默认开启全部采集器,但在某些容器或低配节点上,textfile 或 systemd 采集器会卡住甚至 crash,导致整个 node_exporter 停止响应 /metrics。
实操建议:
- 启动时显式禁用高风险采集器:
--no-collector.textfile --no-collector.systemd - 确认
node_exporter进程监听的是0.0.0.0:9100,不是127.0.0.1:9100(后者在 Kubernetes HostNetwork 模式下也抓不到) - 在 Prometheus target 页面看具体错误:如果显示
context deadline exceeded,八成是采集器阻塞;如果显示connection refused,优先查防火墙和systemctl status node_exporter
集群脑裂时,corosync 日志里反复出现 ERROR [QB] connection failed
这不是网络不通的简单提示,而是 corosync 的 quorum 判定已失效,但 pacemaker 还在尝试同步状态,导致两个子集群各自执行 fencing —— 数据可能被双写破坏。
实操建议:
- 立刻检查
corosync.conf中的quorum.provider:是否为corosync_votequorum,而不是已废弃的corosync_quorum - 确认所有节点时间同步:用
chronyc tracking查 offset,>100ms 就可能触发误判 - 临时规避:在非主子集群节点上运行
pcs cluster stop --all,再逐个pcs cluster start,强制重新协商 quorum
用 consul 做服务发现,check.ttl 设太短反而引发抖动
TTL 不是越小越好。设成 5s,意味着每个服务每 5 秒必须上报一次心跳;网络延迟尖峰、GC 暂停、Consul server 负载高,都可能导致漏报,服务瞬间被标记为 critical 并从 DNS/HTTP 接口摘除。
实操建议:
- 把
check.ttl设为实际最长健康间隔的 3 倍以上,例如服务心跳稳定在 10s,TTL 至少设 30s - 配合
check.interval使用:它只控制客户端上报频率,不影响 TTL 过期逻辑;两者值可以不同 - 生产环境禁用
check.http类主动探测(易受瞬时超时影响),优先用check.ttl+ 客户端主动上报
跨机房部署时,TTL 必须考虑 RTT 波动;单个节点故障不可怕,可怕的是因 TTL 设置失当,把健康节点批量踢出服务列表。










