这个脚本解决什么问题?

服务半夜挂了,是运维最头疼的事。不可能 24 小时盯着,可服务一挂,用户页面全报错,等第二天上班才发现就晚了。

更好的方案是:让脚本每几分钟检查一次服务在不在,掉线了自动拉起来,同时记日志。这样即使半夜挂了,几分钟内就自动恢复了,不用人盯。

脚本全文

用途: 定时检查指定服务是否存活,若掉线自动重启并记录日志,减少人工盯守。

#!/bin/bash

SERVICE="nginx"              # 要盯着谁,改成 mysql / php-fpm 都行
LOG="/var/log/autorestart.log"

if systemctl is-active --quiet "$SERVICE"; then
    echo "[$(date '+%F %T')] $SERVICE 运行正常"
else
    # 服务掉线了:重启,并把这次事故记进日志,方便日后追查
    systemctl restart "$SERVICE"
    echo "[$(date '+%F %T')] $SERVICE 异常,已自动重启" >> "$LOG"
fi

一行行看懂它

  • SERVICE="nginx":把要监控的服务名抽出来做成变量,以后想看别的服务,改这一处就行,不用改逻辑。
  • systemctl is-active --quiet "$SERVICE":is-active 用来判断服务是活是死;--quiet 让它只返回”正常(退出码 0) / 异常(非 0)”、不打印一堆说明——正好适合放进 if 里当判断条件。这是它和 systemctl status 的区别。
  • >> "$LOG":>> 是追加写入,把每次重启记录累积到日志文件里,形成一份”事故台账”,事后能查是第几次、几点挂的。
  • $(date '+%F %T'):输出当前时间(%F 是日期、%T 是时分秒),让每行日志都带上时间戳。

怎么用

vim check_service.sh
chmod +x check_service.sh
crontab -e
# 每 5 分钟检查一次:
*/5 * * * * /root/scripts/check_service.sh

常见坑

现象原因解决
服务确实挂了却不重启服务名写错systemctl list-units 查准确的服务名
判断反了(活着却重启)逻辑写反确认 is-active 返回码:正常返回 0,进 if 真分支
重启报权限不足脚本没以 root 跑crontab 用 root 用户的,或用 sudo

小结

这个脚本的本质是”心跳检测 + 自动恢复“,是运维保活里最基础也最实用的一招。is-active --quiet 一句判断 + systemctl restart 一键拉起 + >> 追加日志,三段式就把”服务保活”这件事自动化了。