定时检查内存使用并告警脚本

wen 实用脚本 3

定时检查内存使用并告警脚本全面指南

目录导读

  1. 为什么要监控内存使用? - 内存泄漏与系统崩溃的隐形杀手
  2. 核心脚本实现 - 从零搭建内存监控告警系统
  3. 告警机制设计 - 邮件/钉钉/企业微信多渠道通知
  4. 定时任务配置 - crontab与systemd timer实战
  5. 常见问题与问答 - 解决脚本运行中的10个关键疑惑

为什么要监控内存使用?

在服务器运维中,内存是决定应用稳定性的核心资源,据Stack Overflow 2023年调查数据显示,超过34%的服务器故障与内存耗尽直接相关,当内存使用率超过90%时,系统会触发OOM Killer(内存溢出杀手),随机终止进程——这可能导致核心业务中断。

定时检查内存使用并告警脚本

典型场景

  • Java应用内存泄漏(如堆内存不断增长)
  • 缓存服务(Redis/Memcached)缓存膨胀
  • 数据库查询未释放临时内存
  • 容器化环境(Docker/K8s)内存限制不当

痛点:人工巡检效率低,且无法实时发现突增。


核心脚本实现:定时检查内存使用并告警脚本

以下脚本基于Bash编写,兼容CentOS 7+/Ubuntu 18.04+,支持自定义阈值:

#!/bin/bash
# 内存监控告警脚本 - memory-monitor.sh
# ===== 配置区域 =====
THRESHOLD=80                 # 内存使用率告警阈值 (%)
ALERT_LOG="/var/log/memory-alert.log"
MAIL_TO="admin@example.com"
# ===== 获取内存使用率 =====
get_mem_usage() {
    # 使用free命令获取内存信息
    local total=$(free -m | awk '/^Mem:/ {print $2}')
    local used=$(free -m | awk '/^Mem:/ {print $3}')
    # 计算使用率(保留两位小数)
    local usage=$(echo "scale=2; $used * 100 / $total" | bc)
    # 输出纯数字(去掉小数)
    echo "$usage" | cut -d. -f1
}
# ===== 核心监控逻辑 =====
mem_usage=$(get_mem_usage)
current_time=$(date "+%Y-%m-%d %H:%M:%S")
hostname=$(hostname)
# 判断是否超过阈值
if [ "$mem_usage" -ge "$THRESHOLD" ]; then
    # 记录告警日志
    echo "$current_time WARNING: Memory usage $mem_usage% (threshold: $THRESHOLD%)" >> "$ALERT_LOG"
    # 获取占用内存前5的进程
    top_processes=$(ps aux --sort=-%mem | head -6 | tail -5)
    # 发送告警(支持邮件/Webhook/钉钉)
    alert_message="⚠️ 服务器 [$hostname] 内存告警
    时间:$current_time
    内存使用率:$mem_usage%
    阈值:$THRESHOLD%
    Top 5 内存进程:
    $top_processes"
    # 邮件告警(需要配置mail命令)
    echo "$alert_message" | mail -s "[ALERT] Server $hostname Memory Usage $mem_usage%" "$MAIL_TO"
    # 可选:钉钉机器人(Webhook)
    # curl -X POST -H "Content-Type: application/json" -d '{"msgtype":"text","text":{"content":"'"$alert_message"'"}}' "https://oapi.dingtalk.com/robot/send?access_token=YOUR_TOKEN"
fi
exit 0

脚本说明

  • 灵活配置:调整THRESHOLD变量即可改变告警阈值
  • 进程分析:自动输出消耗内存最多的5个进程,帮助定位问题
  • 日志持久化:所有告警记录到/var/log/memory-alert.log,便于事后审计

告警机制设计

脚本内置了邮件告警,但实际生产环境需要更丰富的方式:

告警方式 实现方法 优势
邮件 使用mail命令 标准、易集成
钉钉/飞书 Webhook POST请求 即时通知、支持卡片消息
企业微信 机器人API 与办公协同无缝衔接
PagerDuty API调用 适合大企业值班体系

进阶方案:集成Prometheus + Grafana后,可通过Alertmanager实现告警路由与分组。


定时任务配置

方案A:crontab(推荐)
# 每5分钟执行一次监控
*/5 * * * * /opt/scripts/memory-monitor.sh
方案B:systemd timer(更稳定)

创建服务文件:

# /etc/systemd/system/memory-monitor.service
[Service]
ExecStart=/opt/scripts/memory-monitor.sh
# /etc/systemd/system/memory-monitor.timer
[Timer]
OnCalendar=*:0/5  # 每5分钟
Persistent=true

启用:

systemctl daemon-reload
systemctl enable --now memory-monitor.timer

常见问题与问答

Q1:脚本中如何精确获取内存使用率? A:使用free -m获取MB单位数据,通过awk提取total和used字段,再经bc计算百分比,注意echo管道传递给bc时需使用scale控制小数精度。

Q2:为什么告警阈值设为80%而非95%? A:80%是缓冲阈值,内存达到80%时,操作系统会开始使用swap(如果开启),同时OOM Killer的触发风险在90%以上飙升,留出20%缓冲可避免误告警。

Q3:如何区分内存泄漏和正常业务高峰? A:需结合趋势分析,可在脚本中加入历史记录功能(如用rrdtool或文件记录每5分钟的内存值),当内存持续增长而非波动时,才触发二次告警。

Q4:容器环境(Docker)如何监控? A:在容器内使用cat /sys/fs/cgroup/memory/memory.usage_in_bytes获取容器分配内存使用量,配合memory.limit_in_bytes计算使用率,但建议在宿主机层面通过cAdvisorPrometheus node_exporter统一采集。

Q5:告警太多如何抑制? A:实现告警去重机制:脚本中记录上次告警时间,如果距离上次告警时间小于30分钟,则跳过邮件发送,仅追加日志,或集成Alertmanager中的inhibit_rules

Q6:脚本执行权限与路径问题? A:将脚本放置于/opt/scripts目录,确保chmod +x执行权限,crontab中使用绝对路径以避免环境变量问题。

Q7:如何实现Swap监控? A:增加Swap使用率检查:free -m | awk '/^Swap/ {if($2>0) print $3*100/$2}',当Swap使用率>50%且内存>80%时,触发严重告警。

Q8:生产环境下脚本需要加锁防止并发吗? A:是的,使用flockmkdir锁机制,因为crontab间隔可能因系统繁忙导致重叠执行,锁可防止多个实例同时运行。

Q9:如何测试脚本正确性? A:最小化测试环境:在测试服务器上设置THRESHOLD=1,触发告警并检查日志和邮件/钉钉是否收到,也可配合stress命令手动占用内存:stress --vm 2 --vm-bytes 1G --timeout 60

Q10:脚本是否支持ARM架构(树莓派)? A:支持。free命令在所有Linux发行版上一致,bc计算也跨平台,注意树莓派内存较小,建议将阈值调整为70%。


通过本文的定时检查内存使用并告警脚本,你可以用5分钟快速部署一套可靠的内存监控系统,它不仅能在内存膨胀时第一时间推送通知,更能通过输出top进程帮助快速定位原因,结合crontab定时任务,实现7×24小时无人值守运维——这正是现代DevOps工程师必备的生产力工具,立即在你的服务器上运行这个脚本,让内存泄漏无处遁形。

抱歉,评论功能暂时关闭!