Blog.wlens.top
1719 字
9 分钟
CPU 监控报警脚本:Telegram 告警与自动服务重启

项目背景
在服务器运维中,CPU 使用率的突发性飙升是一个常见问题,它可能由恶意攻击、程序 Bug 或流量高峰引起。如果不及时处理,很可能导致服务器响应缓慢甚至完全宕机。这个脚本就是为了解决这一痛点而设计的自动化解决方案。
它会像一个不知疲倦的哨兵,持续监控服务器的 CPU 状态。一旦发现异常,它会立即通过 Telegram 向您告警;如果情况恶化,它会采取“熔断”措施,主动关停核心服务以保护服务器;当危机解除后,它又会自动恢复服务,整个过程无需人工干预。
功能特点
- 实时监控:每秒检测一次服务器的 CPU 使用率。
- 分级告警:
- 预警:当 CPU 使用率持续 10 秒 超过 50%,会立即发送一条 Telegram 消息通知您。
- 熔断:当 CPU 使用率持续 120 秒 超过 50%,脚本会判定为严重故障,并自动停止 Apache 和 PHP 服务,防止资源耗尽。
- 自动恢复:当 CPU 负载恢复正常(低于50%)并稳定持续 120 秒后,脚本会自动重启之前关停的 Apache 和 PHP 服务。
- 高度可定制:您可以轻松修改脚本内的变量,以适应不同的告警阈值、服务命令和 Telegram 配置。
准备工作 (Prerequisites)
在开始之前,请确保您的服务器满足以下条件,并已准备好相关信息。
- 一台 Linux 服务器:本脚本在 CentOS/Debian/Ubuntu 等主流发行版上均可使用。
- 安装
sysstat
和bc
:脚本依赖sar
命令来获取 CPU 信息,它包含在sysstat
包中;bc
则用于浮点数运算。Terminal window # 对于 Debian/Ubuntu 系统sudo apt updatesudo apt install -y sysstat bc# 对于 CentOS/RHEL 系统sudo yum install -y sysstat bc - 一个 Telegram Bot 和它的 Token:
- 在 Telegram 中搜索
BotFather
。 - 发送
/newbot
命令,并按照提示创建您的机器人。 BotFather
会给您一串 Token,形如123456:ABC-DEF1234ghIkl-zyx57W2v1u123456789
,请务必复制并保存好。
- 在 Telegram 中搜索
- 您的 Telegram Chat ID:
- 在 Telegram 中搜索
@userinfobot
。 - 向它发送
/start
,它会返回您的个人信息,其中的 Id 就是您的 Chat ID。
- 在 Telegram 中搜索
使用方法 (How to Use)
步骤 1:创建并编辑脚本
首先,在您的服务器上创建一个脚本文件。
# 创建一个名为 monitor.sh 的文件touch monitor.sh# 使用 nano 或 vim 编辑器打开它nano monitor.sh
然后,将下面的完整代码复制并粘贴到 monitor.sh
文件中。
#!/bin/bash
# --- 用户配置区 ---# 请将这里替换为您自己的信息
# Telegram Bot API TokenTOKEN="YOUR_TELEGRAM_BOT_TOKEN"# Your Telegram chat IDCHAT_ID="YOUR_TELEGRAM_CHAT_ID"
# 停止服务的命令 (请根据您的系统修改)# 如果您使用 systemd (如 CentOS 7+, Debian 8+, Ubuntu 16.04+), 推荐使用下面的命令APACHE_STOP="systemctl stop apache2" # Debian/Ubuntu 使用 apache2, CentOS 使用 httpdPHP_STOP="systemctl stop php7.4-fpm" # 请根据您的 PHP 版本修改
# 启动/重启服务的命令 (请根据您的系统修改)APACHE_START="systemctl restart apache2"PHP_START="systemctl restart php7.4-fpm"
# --- 脚本核心逻辑 ---# 一般无需修改以下内容
# 初始化计数器和标志位high_cpu_duration=0 # 记录CPU持续高负载的时长(秒)low_cpu_duration=0 # 记录CPU持续低负载的时长(秒)is_service_stopped=false # 标记服务是否已被脚本停止
echo "CPU 监控脚本已启动..."
while true; do # 使用 sar 获取 CPU 空闲率,然后计算使用率 (100 - 空闲率) # sar -u 1 1: 每秒采样1次,共采样1次 # tail -n 1: 获取最后一行数据 # awk '{print $NF}': 获取最后一列 (%idle) cpu_idle=$(sar -u 1 1 | tail -n 1 | awk '{print $NF}') cpu_usage=$(echo "100 - $cpu_idle" | bc)
# 检查CPU使用率是否超过50% if (( $(echo "$cpu_usage > 50" | bc -l) )); then ((high_cpu_duration++)) low_cpu_duration=0 # 重置低负载计数器
echo "[$(date)] CPU 持续高负载: ${high_cpu_duration}s, 当前使用率: ${cpu_usage}%"
# 检查持续高负载是否达到 10 秒 (且服务未被停止) # 每10秒发送一次告警,避免刷屏 if (( high_cpu_duration % 10 == 0 )) && [ "$is_service_stopped" = false ]; then message="⚠️ **CPU 持续高负载警告** ⚠️%0A%0A当前使用率: **${cpu_usage}%**%0A持续时间: ${high_cpu_duration} 秒" curl -s -X POST "https://api.telegram.org/bot$TOKEN/sendMessage" -d chat_id="$CHAT_ID" -d text="$message" -d parse_mode="Markdown" > /dev/null fi
# 检查持续高负载是否达到 120 秒 (且服务未被停止) if (( high_cpu_duration >= 120 )) && [ "$is_service_stopped" = false ]; then echo "[$(date)] CPU 持续高负载超过 120 秒,执行服务熔断..." # 停止 Apache 和 PHP eval $APACHE_STOP eval $PHP_STOP is_service_stopped=true # 标记服务已停止
# 发送熔断通知 message="🚨 **服务熔断通知** 🚨%0A%0ACPU 持续高负载超过 120 秒,已自动停止 Apache 和 PHP 服务以保护系统!" curl -s -X POST "https://api.telegram.org/bot$TOKEN/sendMessage" -d chat_id="$CHAT_ID" -d text="$message" -d parse_mode="Markdown" > /dev/null fi else # CPU 负载正常 high_cpu_duration=0 # 重置高负载计数器
# 仅当服务被脚本停止后,才开始计算恢复时间 if [ "$is_service_stopped" = true ]; then ((low_cpu_duration++)) echo "[$(date)] CPU 负载已恢复正常,持续: ${low_cpu_duration}s, 当前使用率: ${cpu_usage}%"
# 检查持续低负载是否达到 120 秒 if (( low_cpu_duration >= 120 )); then echo "[$(date)] CPU 负载稳定正常超过 120 秒,执行服务恢复..." # 重启 Apache 和 PHP eval $APACHE_START eval $PHP_START is_service_stopped=false # 重置标志位 low_cpu_duration=0 # 重置计数器
# 发送恢复通知 message="✅ **服务恢复通知** ✅%0A%0ACPU 负载已恢复正常,Apache 和 PHP 服务已自动重启!" curl -s -X POST "https://api.telegram.org/bot$TOKEN/sendMessage" -d chat_id="$CHAT_ID" -d text="$message" -d parse_mode="Markdown" > /dev/null fi fi fi
# 每秒循环一次 sleep 1done
步骤 2:修改配置
这是最重要的一步! 您需要根据您的实际情况修改脚本头部的用户配置区:
TOKEN="YOUR_TELEGRAM_BOT_TOKEN"
:将YOUR_TELEGRAM_BOT_TOKEN
替换为您从BotFather
获取的真实 Token。CHAT_ID="YOUR_TELEGRAM_CHAT_ID"
:替换为您自己的 Chat ID。- 修改服务命令:
- 脚本中的
APACHE_STOP
等命令默认使用了systemd
(现代 Linux 发行版的主流服务管理器)。 - 检查您的服务名称:
- 在 Debian/Ubuntu 上,Apache 通常叫
apache2
。 - 在 CentOS/RHEL 上,Apache 通常叫
httpd
。 - PHP-FPM 的服务名通常与版本有关,如
php7.4-fpm
,php8.1-fpm
。您可以通过systemctl status php*
来查找正确的服务名。
- 在 Debian/Ubuntu 上,Apache 通常叫
- 按需修改脚本中的
APACHE_STOP
,PHP_STOP
,APACHE_START
,PHP_START
的值为您的正确命令。
- 脚本中的
步骤 3:赋予执行权限
保存并退出编辑器后,给脚本添加执行权限。
chmod +x monitor.sh
步骤 4:后台运行脚本
为了让脚本在您关闭终端后依然能持续运行,我们需要让它在后台执行。推荐使用 nohup
命令。
nohup ./monitor.sh &
执行后,您会看到类似 [1] 12345
的输出,并提示日志将输出到 nohup.out
文件。现在,脚本已经在后台默默守护您的服务器了。
- 查看实时日志:
tail -f nohup.out
- 停止脚本:
- 找到脚本的进程ID(PID):
ps aux | grep monitor.sh
- 杀死进程:
kill <PID>
(将<PID>
替换为您找到的数字)
- 找到脚本的进程ID(PID):
现在,您的自动化运维哨兵已经正式上岗了!
CPU 监控报警脚本:Telegram 告警与自动服务重启
https://blog.wlens.top/posts/升级版监控cpu并向telegram发送警报/