真正可用的systemd服务自启配置需组合restart=on-failure、restartsec=5、startlimitintervalsec=60、startlimitburst=3和restartpreventexitstatus=255,避免雪崩并留人工介入窗口。

用 systemd 实现服务崩溃后自动拉起,但别只写 Restart=always
单纯加 Restart=always 很容易导致雪崩:服务反复崩溃又重启,把日志打满、端口占死、甚至拖垮节点。真正可用的配置必须叠加限制条件。
-
Restart=on-failure更稳妥——只在非 0 退出码或被信号终止时重启,避免正常退出后误拉起 - 务必配
StartLimitIntervalSec=60和StartLimitBurst=3,防止 1 分钟内连续失败超 3 次就彻底停服,留出人工介入窗口 - 如果服务依赖网络或远程存储,加
RestartPreventExitStatus=255(比如 curl 超时返回 255)可避免把临时网络抖动当故障处理 - 示例片段:
[Service] Restart=on-failure RestartSec=5 StartLimitIntervalSec=60 StartLimitBurst=3 RestartPreventExitStatus=255
集群级进程存活检测不能只靠 ps aux | grep
这种写法在容器化或 systemd 管理环境下极不可靠:进程名被截断、grep 自身混入结果、cgroup 隔离后 ps 看不到跨 namespace 进程。
- 优先用
systemctl is-active <code>service_name判断服务状态,它走的是 dbus 协议,准确反映 systemd 管理的真实生命周期 - 对非 systemd 进程(如裸跑的 Python 脚本),改用
pgrep -f "python.*my_worker.py",-f匹配完整命令行,比grep少一层管道污染 - 在监控脚本里加超时控制:
timeout 5 systemctl is-active myapp.service || echo "timeout",避免因 dbus 卡住导致整个巡检阻塞
node_exporter 默认指标不够用,关键集群维度得自己加
默认采集的 CPU、内存、磁盘指标只能告诉你“机器快挂了”,但无法定位是哪个服务或租户吃掉了资源。集群监控必须带标签下钻能力。
- 用
--collector.textfile.directory配合定时脚本,把每个服务的docker stats --no-stream或kubectl top pod结果写成.prom文件,让node_exporter暴露为自定义指标(如container_cpu_usage_cores{job="myapp", instance="node-01"}) - 禁用冗余采集器节省开销:
--no-collector.wifi --no-collector.zfs,ZFS 在 Linux 集群几乎不用,WiFi 更是干扰项 - 注意时间戳精度:文本文件里每行末尾加
# TYPE xxx gauge注释,并确保写入时间与采集周期对齐,否则 Prometheus 抓取会丢点
自动恢复脚本里调 curl 或 ssh 前,先做连接性兜底
故障恢复链路上任何一环超时或失败,都会让“自动恢复”变成“自动失联”。不能假设网络永远通、目标端口永远开、密钥永远有效。
- 用
nc -z -w 3 target-host 22 && ssh ...替代裸ssh,3 秒内连不上就跳过,不卡住后续步骤 - 调用 API 前先
curl -sfI -m 5 https://api.example.com/health,-s静默错误、-f失败不输出、-m 5限总耗时,靠返回码判断是否值得继续 - 所有远程操作加
set -e和set -o pipefail,但关键步骤后立刻用|| true显式忽略非致命错误(比如清理旧日志失败不影响主流程)
集群自动恢复最麻烦的不是写脚本,而是厘清“什么算恢复成功”——是进程起来了?端口能连了?还是第一个 HTTP 请求返回 200?这个判定标准一旦模糊,所有自动逻辑都会在边界 case 上失效。










