系统资源监控与邮件告警
实用Shell脚本:系统资源监控与邮件告警全实现
在服务器运维中,实时监控系统资源并及时响应异常是保障服务稳定的关键。本文将分享一个实用的Shell脚本,可监控CPU、内存、硬盘使用率、磁盘IO等待时间及网络流量,并在指标超限时自动发送邮件告警,帮助运维人员快速发现并处理问题。
一、脚本功能与监控指标说明
本脚本主要实现三大监控需求:
- 基础资源监控:当CPU、内存、硬盘使用率超过80%时告警
- 磁盘IO监控:当IO await(IO等待时间)大于50ms时告警
- 网络流量监控:当下载/上传速度超过10MB/s(可自定义)时告警
所有告警信息将通过邮件发送到指定邮箱,支持163、QQ、139等主流邮箱的SMTP服务。
二、环境准备与依赖安装
1. 必要工具安装
脚本依赖以下工具,需提前安装:
# CentOS/RHEL系统
yum install -y msmtp sysstat bc# Ubuntu/Debian系统
apt-get update && apt-get install -y msmtp sysstat bc
msmtp
:用于发送邮件的轻量SMTP客户端sysstat
:提供iostat
命令,用于监控磁盘IObc
:用于浮点数计算(网络流量换算)
2. 邮箱SMTP服务配置
以QQ邮箱为例(163/139邮箱配置类似):
- 登录邮箱网页版,进入「设置→账户」
- 开启「POP3/SMTP服务」,按提示获取授权码(非登录密码)
- 配置
msmtp
邮件客户端:
# 创建配置文件
cat > ~/.msmtprc << EOF
account default
host smtp.qq.com # 163邮箱为smtp.163.com
port 465 # QQ邮箱SSL端口,163邮箱可使用465或587
from 你的邮箱@qq.com
auth on
user 你的邮箱@qq.com
password 你的授权码
tls on
tls_starttls off
EOF# 设置权限(必须为600,否则msmtp拒绝使用)
chmod 600 ~/.msmtprc
三、完整监控脚本实现
#!/bin/bash
# 系统资源监控与邮件告警脚本
# 作者:运维笔记
# 版本:v1.0# ======================
# 配置区(请根据实际修改)
# ======================
# 监控阈值设置
CPU_ALERT=80 # CPU使用率阈值(%)
MEM_ALERT=80 # 内存使用率阈值(%)
DISK_ALERT=80 # 磁盘使用率阈值(%)
IO_ALERT=50 # IO等待阈值(ms)
NET_ALERT=10 # 网络流量阈值(MB/s)# 网络接口(用ifconfig/ip addr查看,如eth0、ens33)
NET_IF="ens33"# 邮件设置
TO_EMAIL="接收告警的邮箱@qq.com"
SMTP_USER="发送邮箱@qq.com" # 与~/.msmtprc中的from一致# ======================
# 邮件发送函数
# ======================
send_alert() {local subject=$1local message=$2local email_content="Subject: $subject\n\n$message\n\n监控时间: $(date +'%Y-%m-%d %H:%M:%S')\n服务器IP: $(hostname -I | awk '{print $1}')"# 发送邮件echo -e "$email_content" | msmtp --from="$SMTP_USER" "$TO_EMAIL"if [ $? -eq 0 ]; thenecho "告警邮件发送成功:$subject"elseecho "告警邮件发送失败!"fi
}# ======================
# 监控函数
# ======================
# 1. CPU使用率监控
check_cpu() {# 获取CPU使用率(用户+系统)local cpu_usage=$(top -bn1 | grep "Cpu(s)" | awk '{print $2 + $4}')local cpu_rounded=$(printf "%.0f" "$cpu_usage")echo "当前CPU使用率:${cpu_rounded}%"if [ "$cpu_rounded" -ge "$CPU_ALERT" ]; thensend_alert "【紧急告警】CPU使用率过高" "CPU使用率已达${cpu_rounded}%,超过阈值${CPU_ALERT}%!"fi
}# 2. 内存使用率监控
check_memory() {# 计算内存使用率(已用/总内存)local mem_usage=$(free | grep Mem | awk '{printf "%.0f", $3/$2*100}')echo "当前内存使用率:${mem_usage}%"if [ "$mem_usage" -ge "$MEM_ALERT" ]; thensend_alert "【紧急告警】内存使用率过高" "内存使用率已达${mem_usage}%,超过阈值${MEM_ALERT}%!"fi
}# 3. 磁盘使用率监控(根分区)
check_disk() {# 获取根分区使用率local disk_usage=$(df -h / | awk 'NR==2{print $5}' | tr -d '%')echo "当前根分区使用率:${disk_usage}%"if [ "$disk_usage" -ge "$DISK_ALERT" ]; thensend_alert "【紧急告警】磁盘空间不足" "根分区使用率已达${disk_usage}%,超过阈值${DISK_ALERT}%!"fi
}# 4. 磁盘IO等待监控
check_io() {# 检查iostat是否安装if ! command -v iostat &> /dev/null; thenecho "未安装iostat,跳过IO检查"returnfi# 获取IO等待时间(取两次采样平均值)local io_wait=$(iostat -x 1 2 | awk '/^avg-cpu/ {getline; print $10}')local io_rounded=$(printf "%.0f" "$io_wait")echo "当前磁盘IO等待时间:${io_rounded}ms"if [ "$io_rounded" -ge "$IO_ALERT" ]; thensend_alert "【紧急告警】磁盘IO等待过高" "磁盘IO等待时间已达${io_rounded}ms,超过阈值${IO_ALERT}ms!"fi
}# 5. 网络流量监控
check_network() {# 检查网络接口是否存在if [ ! -d "/sys/class/net/$NET_IF" ]; thenecho "网络接口$NET_IF不存在,跳过流量检查"returnfi# 第一次采样(字节数)local rx1=$(cat /sys/class/net/$NET_IF/statistics/rx_bytes)local tx1=$(cat /sys/class/net/$NET_IF/statistics/tx_bytes)sleep 1 # 间隔1秒# 第二次采样local rx2=$(cat /sys/class/net/$NET_IF/statistics/rx_bytes)local tx2=$(cat /sys/class/net/$NET_IF/statistics/tx_bytes)# 计算每秒流量(转换为MB/s)local rx_mbps=$(echo "scale=2; ($rx2 - $rx1)/1024/1024" | bc)local tx_mbps=$(echo "scale=2; ($tx2 - $tx1)/1024/1024" | bc)echo "当前网络流量:下载${rx_mbps}MB/s,上传${tx_mbps}MB/s"# 下载流量告警if (( $(echo "$rx_mbps >= $NET_ALERT" | bc -l) )); thensend_alert "【紧急告警】下载流量过高" "下载速度已达${rx_mbps}MB/s,超过阈值${NET_ALERT}MB/s!"fi# 上传流量告警if (( $(echo "$tx_mbps >= $NET_ALERT" | bc -l) )); thensend_alert "【紧急告警】上传流量过高" "上传速度已达${tx_mbps}MB/s,超过阈值${NET_ALERT}MB/s!"fi
}# ======================
# 主程序执行
# ======================
echo "===== 开始系统资源监控($(date)) ====="
check_cpu
check_memory
check_disk
check_io
check_network
echo "===== 监控结束 ====="
四、脚本使用与调试
1. 脚本部署
# 保存脚本为system_monitor.sh
chmod +x system_monitor.sh # 赋予执行权限
./system_monitor.sh # 手动执行测试
2. 常见问题调试
- 邮件发送失败:检查
~/.msmtprc
配置(尤其是授权码)、服务器防火墙是否开放SMTP端口(465/587) - 网络接口错误:用
ip addr
确认接口名(如ens33
),修改NET_IF
参数 - IO检查失败:确保已安装
sysstat
(提供iostat
命令)
3. 定时执行(推荐)
通过crontab
设置定时任务,实现持续监控:
# 每5分钟执行一次
echo "*/5 * * * * /root/system_monitor.sh >> /var/log/system_monitor.log 2>&1" | crontab -
五、脚本扩展建议
- 多磁盘监控:修改
check_disk
函数,遍历所有挂载点(df -h | grep -v tmpfs
) - 告警频率限制:添加文件锁机制,避免短时间内重复发送同一告警
- 历史数据记录:将监控结果写入日志文件,便于趋势分析
- 多接收人支持:修改
TO_EMAIL
为逗号分隔的邮箱列表
通过这个脚本,运维人员可以实时掌握系统资源状态,及时发现并处理潜在问题。根据实际需求调整阈值和监控频率,可有效提升服务器稳定性。