在系统负载持续过高时自动重启指定服务脚本

免费个人运维知识库,欢迎您的订阅:literator_ray.flowus.cn

这是一个系统负载监控脚本,主要功能是在系统负载持续过高时自动重启指定服务,并具备完善的安全机制。

一、脚本功能描述

  1. 负载监控机制

    • 实时监控​:每 ​10秒​ 检测一次系统1分钟平均负载

    • 阈值判断​:使用 bc命令精确比较浮点数负载值

    • 触发条件​:

      • 当负载 ​连续6次​(持续60秒)≥阈值(默认20)时触发重启

      • 低于阈值时自动重置计数

  2. 自动服务管理​:

    • 重启预定义的 TARGET_SERVICE(如 apigate

    • 执行标准命令:systemctl restart ${TARGET_SERVICE}

  3. 安全保护机制​:

    • 冷却期​:重启后进入 ​5分钟冷却期​(300秒),防止反复重启

    • 计数器重置​:负载正常时自动清零连续计数

  4. 告警与日志​:

    • 实时日志

      • 记录时间戳、负载值、计数器状态

      • 日志路径:/data/scripts/log/load_monitor.log

    • 企微告警

      • 重启时自动发送消息到企业微信机器人

      • 包含关键信息:服务器IP、负载值、重启服务名

  5. 告警流程

在这里插入图片描述

可以根据自己的实际需求修改脚本

二、脚本内容

#!/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

欢迎您提出问题,并指正代码中的不足

请不要以此视为定论,这只是我的个人经验

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

黑疯雷

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值