免费个人运维知识库,欢迎您的订阅:literator_ray.flowus.cn
这是一个系统负载监控脚本,主要功能是在系统负载持续过高时自动重启指定服务,并具备完善的安全机制。
一、脚本功能描述
-
负载监控机制
-
实时监控:每 10秒 检测一次系统1分钟平均负载
-
阈值判断:使用
bc
命令精确比较浮点数负载值 -
触发条件:
-
当负载 连续6次(持续60秒)≥阈值(默认20)时触发重启
-
低于阈值时自动重置计数
-
-
-
自动服务管理:
-
重启预定义的
TARGET_SERVICE
(如apigate
) -
执行标准命令:
systemctl restart ${TARGET_SERVICE}
-
-
安全保护机制:
-
冷却期:重启后进入 5分钟冷却期(300秒),防止反复重启
-
计数器重置:负载正常时自动清零连续计数
-
-
告警与日志:
-
实时日志
-
记录时间戳、负载值、计数器状态
-
日志路径:
/data/scripts/log/load_monitor.log
-
-
企微告警
-
重启时自动发送消息到企业微信机器人
-
包含关键信息:服务器IP、负载值、重启服务名
-
-
-
告警流程
可以根据自己的实际需求修改脚本
二、脚本内容
#!/bin/bash
# load_monitor.sh
# 脚本目的,因服务会存在偶发持续一段占用系统load资源的异常,且短时间内无法优化处理,因此需要实时监控系统负载
# 当系统负载持续增高,则重启该服务【注意:在明确是某个服务引起的,再用此脚本,存在风险】
# 监控机制:
# 每 10 秒检测一次系统负载
# 当负载连续 6 次(即 60 秒)≥ 20 时触发重启
# 低于阈值时自动重置计数
# 安全保护措施:
# 服务重启后进入 5 分钟冷却期(防止反复重启)
# 实时输出带时间戳的状态日志
# 精确浮点数比较(使用 bc 命令)
# 监控配置
TARGET_SERVICE="node_exporter" # 需要重启的服务名称
THRESHOLD='20' # 触发重启的负载阈值
CHECK_INTERVAL=10 # 检查间隔(秒)
SUSTAINED_CHECKS=$((60 / CHECK_INTERVAL)) # 持续 1 分钟需要的检查次数
# 状态跟踪
high_load_counter=0
# 服务器IP
IP=`ifconfig eth0|grep 'inet '|awk '{print$2}'`
echo "开始监控系统负载。当 1 分钟平均负载持续 ${THRESHOLD}+ 超过 1 分钟时,将重启 ${TARGET_SERVICE} 服务" >> /data/scripts/log/load_monitor.log
echo "检查间隔:${CHECK_INTERVAL}秒 | 连续阈值:${SUSTAINED_CHECKS}次" >> /data/scripts/log/load_monitor.log
while true; do
# 获取当前 1 分钟平均负载(从 /proc/loadavg 获取第一列)
load=$(awk '{print $1}' /proc/loadavg)
# 浮点数比较(bash 内建不支持,使用 bc)
if (( $(echo "$load >= $THRESHOLD" | bc -l) )); then
((high_load_counter++))
echo "$(date) - 负载过高: ${load} (连续计数: ${high_load_counter}/${SUSTAINED_CHECKS})" >> /data/scripts/log/load_monitor.log
# 达到持续阈值则重启服务
if [ $high_load_counter -ge $SUSTAINED_CHECKS ]; then
echo "$(date) - 触发重启: systemctl restart ${TARGET_SERVICE}" >> /data/scripts/log/load_monitor.log
file_content="$(date) - ${IP} 负载过高: ${load} (连续1分钟计数: 共触发${high_load_counter}次/重启阈值${SUSTAINED_CHECKS}次) ,触发 ${TARGET_SERVICE} 自动重启"
systemctl restart "${TARGET_SERVICE}"
data=$(jq -n --arg msg "$file_content" '{msgtype: "text", text: {content: $msg}}')
curl -H "Content-Type: application/json" -d "$data" https://zyff.bjt.beijing.gov.cn/gjfw/qywxgj/webhook/send?key=56bf3b09-19b7-49cd-bf1f-977bdc67c1d5
# 重置计数器并跳过冷却期
high_load_counter=0
sleep 300 # 重启后等待 5 分钟冷却
continue
fi
else
# 负载低于阈值时重置计数器
if [ $high_load_counter -ne 0 ]; then
echo "$(date) - 负载恢复正常: ${load} 重置计数器" >> /data/scripts/log/load_monitor.log
high_load_counter=0
fi
fi
sleep $CHECK_INTERVAL
done
三、配置 systemd 服务实现后台运行(推荐)
创建 /etc/systemd/system/load-monitor.service
[Unit]
Description=Load Monitor Service
After=network.target
[Service]
User=root
ExecStart=/data/scripts/load_monitor.sh
Restart=always
[Install]
WantedBy=multi-user.target
启用服务:
systemctl daemon-reload
systemctl enable --now load-monitor.service
欢迎您提出问题,并指正代码中的不足
请不要以此视为定论,这只是我的个人经验