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

项目背景#

在服务器运维中,CPU 使用率的突发性飙升是一个常见问题,它可能由恶意攻击、程序 Bug 或流量高峰引起。如果不及时处理,很可能导致服务器响应缓慢甚至完全宕机。这个脚本就是为了解决这一痛点而设计的自动化解决方案。

它会像一个不知疲倦的哨兵,持续监控服务器的 CPU 状态。一旦发现异常,它会立即通过 Telegram 向您告警;如果情况恶化,它会采取“熔断”措施,主动关停核心服务以保护服务器;当危机解除后,它又会自动恢复服务,整个过程无需人工干预。

功能特点#

  • 实时监控:每秒检测一次服务器的 CPU 使用率。
  • 分级告警
    1. 预警:当 CPU 使用率持续 10 秒 超过 50%,会立即发送一条 Telegram 消息通知您。
    2. 熔断:当 CPU 使用率持续 120 秒 超过 50%,脚本会判定为严重故障,并自动停止 Apache 和 PHP 服务,防止资源耗尽。
  • 自动恢复:当 CPU 负载恢复正常(低于50%)并稳定持续 120 秒后,脚本会自动重启之前关停的 Apache 和 PHP 服务。
  • 高度可定制:您可以轻松修改脚本内的变量,以适应不同的告警阈值、服务命令和 Telegram 配置。

准备工作 (Prerequisites)#

在开始之前,请确保您的服务器满足以下条件,并已准备好相关信息。

  1. 一台 Linux 服务器:本脚本在 CentOS/Debian/Ubuntu 等主流发行版上均可使用。
  2. 安装 sysstatbc:脚本依赖 sar 命令来获取 CPU 信息,它包含在 sysstat 包中;bc 则用于浮点数运算。
    Terminal window
    # 对于 Debian/Ubuntu 系统
    sudo apt update
    sudo apt install -y sysstat bc
    # 对于 CentOS/RHEL 系统
    sudo yum install -y sysstat bc
  3. 一个 Telegram Bot 和它的 Token
    • 在 Telegram 中搜索 BotFather
    • 发送 /newbot 命令,并按照提示创建您的机器人。
    • BotFather 会给您一串 Token,形如 123456:ABC-DEF1234ghIkl-zyx57W2v1u123456789,请务必复制并保存好。
  4. 您的 Telegram Chat ID
    • 在 Telegram 中搜索 @userinfobot
    • 向它发送 /start,它会返回您的个人信息,其中的 Id 就是您的 Chat ID。

使用方法 (How to Use)#

步骤 1:创建并编辑脚本#

首先,在您的服务器上创建一个脚本文件。

Terminal window
# 创建一个名为 monitor.sh 的文件
touch monitor.sh
# 使用 nano 或 vim 编辑器打开它
nano monitor.sh

然后,将下面的完整代码复制并粘贴monitor.sh 文件中。

#!/bin/bash
# --- 用户配置区 ---
# 请将这里替换为您自己的信息
# Telegram Bot API Token
TOKEN="YOUR_TELEGRAM_BOT_TOKEN"
# Your Telegram chat ID
CHAT_ID="YOUR_TELEGRAM_CHAT_ID"
# 停止服务的命令 (请根据您的系统修改)
# 如果您使用 systemd (如 CentOS 7+, Debian 8+, Ubuntu 16.04+), 推荐使用下面的命令
APACHE_STOP="systemctl stop apache2" # Debian/Ubuntu 使用 apache2, CentOS 使用 httpd
PHP_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 1
done

步骤 2:修改配置#

这是最重要的一步! 您需要根据您的实际情况修改脚本头部的用户配置区

  1. TOKEN="YOUR_TELEGRAM_BOT_TOKEN":将 YOUR_TELEGRAM_BOT_TOKEN 替换为您从 BotFather 获取的真实 Token。
  2. CHAT_ID="YOUR_TELEGRAM_CHAT_ID":替换为您自己的 Chat ID。
  3. 修改服务命令
    • 脚本中的 APACHE_STOP 等命令默认使用了 systemd(现代 Linux 发行版的主流服务管理器)。
    • 检查您的服务名称
      • 在 Debian/Ubuntu 上,Apache 通常叫 apache2
      • 在 CentOS/RHEL 上,Apache 通常叫 httpd
      • PHP-FPM 的服务名通常与版本有关,如 php7.4-fpm, php8.1-fpm。您可以通过 systemctl status php* 来查找正确的服务名。
    • 按需修改脚本中的 APACHE_STOP, PHP_STOP, APACHE_START, PHP_START 的值为您的正确命令。

步骤 3:赋予执行权限#

保存并退出编辑器后,给脚本添加执行权限。

Terminal window
chmod +x monitor.sh

步骤 4:后台运行脚本#

为了让脚本在您关闭终端后依然能持续运行,我们需要让它在后台执行。推荐使用 nohup 命令。

Terminal window
nohup ./monitor.sh &

执行后,您会看到类似 [1] 12345 的输出,并提示日志将输出到 nohup.out 文件。现在,脚本已经在后台默默守护您的服务器了。

  • 查看实时日志tail -f nohup.out
  • 停止脚本
    1. 找到脚本的进程ID(PID):ps aux | grep monitor.sh
    2. 杀死进程:kill <PID> (将 <PID> 替换为您找到的数字)

现在,您的自动化运维哨兵已经正式上岗了!

CPU 监控报警脚本:Telegram 告警与自动服务重启
https://blog.wlens.top/posts/升级版监控cpu并向telegram发送警报/
作者
Lao Wang
发布于
2023-12-23
许可协议
CC BY-NC-SA 4.0