Linux脚本监控服务器异常告警
用Linux脚本监控服务器异常并自动告警,新手也能实现
服务器半夜宕机、磁盘写满、CPU飙高,你总不能一直盯着看。
更好的办法是写一个简单的 Linux 脚本,定期检查各项指标,发现异常时自动通知你——邮件、钉钉、企业微信都可以。
本文围绕 Linux脚本监控服务器异常告警 这个需求,从零开始带你写完脚本、配置定时任务、测试验证,文末还整理了常见报错和避坑说明。
写脚本之前需要准备什么
执行本文操作需要一个 Linux 服务器(CentOS 7/8、Ubuntu 20.04 均可),你至少有 root 或 sudo 权限。
另外需要确认三条命令是否存在:free、df、ps(一般预装)。
如果想用邮件告警,需要安装 mailx 或 sendmail。
如果想用钉钉/企业微信机器人,只需要一个 Webhook 地址就行。
检查邮件服务:
which mailx || yum install -y mailx # CentOS/RHEL
which mailx || apt install -y mailx # Ubuntu/Debian
编写一个支持多种告警方式的监控脚本
下面这个脚本会检查 CPU 使用率、内存使用率、磁盘占用、以及一个关键进程(比如 nginx)是否存活。
超过阈值就发告警。
你可以直接复制到 /usr/local/bin/server_monitor.sh。
#!/bin/bash
# 服务器异常监控脚本 —— 可自定义阈值和告警方式
# ---------- 配置区域 ----------
ALERT_CPU=80 # CPU使用率超过此值告警(% )
ALERT_MEM=90 # 内存使用率
ALERT_DISK=85 # 磁盘占用率
PROCESS_CHECK="nginx" # 要检查的进程名,留空表示不检查
# 告警方式:email / dingtalk / wework (选一个)
ALERT_METHOD="email"
# 邮件收件人(email方式必填)
EMAIL_TO="admin@example.com"
# 钉钉/企微机器人 Webhook URL
WEBHOOK_URL="https://oapi.dingtalk.com/robot/send?access_token=你的token"
# ---------- 配置结束 ----------
HOST=$(hostname)
NOW=$(date '+%Y-%m-%d %H:%M:%S')
MESSAGE=""
# 获取CPU使用率(取空闲值反算)
CPU_IDLE=$(top -bn1 | grep "Cpu(s)" | awk '{print $8}' | cut -d'%' -f1)
CPU_USED=$(echo "100 - $CPU_IDLE" | bc)
if (( $(echo "$CPU_USED > $ALERT_CPU" | bc -l) )); then
MESSAGE+="CPU使用率过高: ${CPU_USED}% (阈值 ${ALERT_CPU}%) \n"
fi
# 内存使用率
MEM_TOTAL=$(free -m | awk '/Mem:/{print $2}')
MEM_USED=$(free -m | awk '/Mem:/{print $3}')
if [ "$MEM_TOTAL" -gt 0 ]; then
MEM_PERCENT=$(echo "scale=2; $MEM_USED * 100 / $MEM_TOTAL" | bc)
if (( $(echo "$MEM_PERCENT > $ALERT_MEM" | bc -l) )); then
MESSAGE+="内存使用率过高: ${MEM_PERCENT}% (阈值 ${ALERT_MEM}%) \n"
fi
fi
# 磁盘占用率(检查根分区 / )
DISK_USED=$(df / | tail -1 | awk '{print $5}' | sed 's/%//')
if [ "$DISK_USED" -gt "$ALERT_DISK" ]; then
MESSAGE+="磁盘占用率过高: ${DISK_USED}% (阈值 ${ALERT_DISK}%) \n"
fi
# 检查进程
if [ -n "$PROCESS_CHECK" ]; then
ps aux | grep -v grep | grep -q "$PROCESS_CHECK"
if [ $? -ne 0 ]; then
MESSAGE+="进程 $PROCESS_CHECK 未运行! \n"
fi
fi
# 如果没有任何异常,直接退出
if [ -z "$MESSAGE" ]; then
exit 0
fi
MESSAGE="[服务器告警] $HOST 时间: $NOW \n$MESSAGE"
# 根据告警方式发送
case "$ALERT_METHOD" in
email)
echo -e "$MESSAGE" | mail -s "服务器异常告警 $HOST" "$EMAIL_TO"
;;
dingtalk)
curl -s -X POST -H "Content-Type: application/json" \
-d "{\"msgtype\":\"text\",\"text\":{\"content\":\"$MESSAGE\"}}" \
"$WEBHOOK_URL" > /dev/null
;;
wework)
curl -s -X POST -H "Content-Type: application/json" \
-d "{\"msgtype\":\"text\",\"text\":{\"content\":\"$MESSAGE\"}}" \
"$WEBHOOK_URL" > /dev/null
;;
esac
注意:脚本中使用了 bc 做浮点运算,如果系统没装需要先安装:yum install -y bc 或 apt install -y bc。
保存后赋予执行权限:
chmod +x /usr/local/bin/server_monitor.sh
通过 crontab 设置定时执行
脚本写好了,还需要让它每隔几分钟跑一次。
执行 crontab -e 添加一行:
*/5 * * * * /bin/bash /usr/local/bin/server_monitor.sh
这表示每 5 分钟执行一次。
保存后检查定时任务是否生效:
crontab -l
看到刚加的行就对了。
避坑指南:新手容易忽略的三个问题
- 脚本路径问题:crontab 默认环境变量有限,建议在脚本内使用绝对路径,或者第一行用
#!/bin/bash并显式source /etc/profile。上面脚本已经用了绝对路径调用命令,一般没问题。 - 邮件告警发不出去:先手动执行
echo "test" | mail -s "test" your@email.com测试邮件服务是否正常。如果收不到,检查mailx配置(/etc/mail.rc设置 smtp)。 - 告警频率过高:如果异常持续,每 5 分钟就会收到一次告警,容易疲劳。建议脚本内增加去重逻辑(记录上次告警时间,同一指标在 30 分钟内不重复发送),本文聚焦基础,暂未实现,你可以按需优化。
高频问题解答 (FAQ)
Q:没有公网 SMTP 服务器,能用其他方式告警吗?
A:可以。推荐使用钉钉或企业微信机器人,只需要在群里添加机器人拿到 Webhook URL,然后将脚本中的 ALERT_METHOD 改为 dingtalk 或 wework,填好 WEBHOOK_URL 即可。
Q:脚本检查了 CPU、内存、磁盘,还能加其他指标吗?
A:可以扩展。比如检查网络流量、特定端口(netstat -an | grep :80)、系统负载(uptime)等。只需在脚本中添加对应的判断逻辑,把异常信息拼入 MESSAGE 变量即可。
Q:如何测试脚本是否能正常触发告警?
A:手动把阈值调低(比如把 ALERT_CPU=80 改成 ALERT_CPU=10),然后直接运行脚本 /bin/bash /usr/local/bin/server_monitor.sh,观察是否收到告警消息。测试完记得改回正常阈值。
最后的效果验证
完成配置后,至少等待一个定时周期(5分钟)看看是否收到告警。
你也可以用上述方法模拟阈值来验证。
如果一切正常,你的 Linux 服务器就已经拥有了基础的 脚本监控和异常告警能力。
以后再也不用半夜惊醒手动登服务器了。
如果你正在部署这个方案,建议先按本文的步骤完整跑一遍,再根据你自己的环境(比如进程名、阈值、告警方式)做微调;
遇到报错时优先回看上面的避坑部分,通常都能解决。