一、为什么需要系统资源监控与自动扩容

想象一下,你正在运营一个电商网站,突然遇到"双十一"大促,流量瞬间暴涨。如果服务器资源不足,网站就会卡顿甚至崩溃,用户投诉接踵而至。这时候,如果有个"智能管家"能自动监控资源使用情况,并在需要时扩容,是不是很美妙?

这就是系统资源监控与自动扩容的价值所在。通过Shell脚本,我们可以实现这个"智能管家"的功能。它就像个尽职的保安,24小时盯着CPU、内存、磁盘这些关键指标,一旦发现资源紧张,就自动触发扩容操作。

二、监控系统资源的基础命令

在Linux系统中,有很多现成的命令可以帮助我们获取系统资源信息。下面介绍几个最常用的:

  1. CPU监控:使用topmpstat命令
# 获取CPU使用率(示例使用mpstat命令)
mpstat 1 1 | awk '/Average/ {print 100 - $NF"%"}'
# 解释:
# mpstat 1 1 - 采样1秒,输出1次报告
# awk部分 - 提取最后一列(空闲CPU),计算使用率
  1. 内存监控:使用free命令
# 获取内存使用率
free -m | awk '/Mem:/ {print $3/$2 * 100.0"%"}'
# 解释:
# free -m - 以MB为单位显示内存使用情况
# awk部分 - 计算已用内存占总内存的百分比
  1. 磁盘监控:使用df命令
# 获取根分区使用率
df -h / | awk 'NR==2 {print $5}'
# 解释:
# df -h / - 以人类可读格式显示根分区使用情况
# awk部分 - 提取第二行第五列(使用百分比)
  1. 网络监控:使用iftopnload命令
# 安装iftop(如果尚未安装)
sudo apt install iftop -y
# 监控网络流量
iftop -t -s 1 -n -N
# 解释:
# -t 使用文本界面
# -s 1 每秒刷新一次
# -n 不解析主机名
# -N 不解析端口号

三、编写完整的监控脚本

现在,我们把上面的命令整合成一个完整的监控脚本。这个脚本会定期检查系统资源,并在资源使用超过阈值时发出警报。

#!/bin/bash
# 系统资源监控脚本
# 作者:Shell专家
# 版本:1.0

# 配置阈值
CPU_THRESHOLD=80      # CPU使用率阈值(%)
MEM_THRESHOLD=85      # 内存使用率阈值(%)
DISK_THRESHOLD=90     # 磁盘使用率阈值(%)
LOG_FILE="/var/log/system_monitor.log"  # 日志文件路径

# 创建日志目录(如果不存在)
mkdir -p $(dirname "$LOG_FILE")

# 获取当前时间戳
timestamp() {
    date "+%Y-%m-%d %H:%M:%S"
}

# 记录日志函数
log() {
    echo "[$(timestamp)] $1" >> "$LOG_FILE"
}

# 检查CPU使用率
check_cpu() {
    local cpu_usage=$(mpstat 1 1 | awk '/Average/ {print 100 - $NF}')
    if (( $(echo "$cpu_usage > $CPU_THRESHOLD" | bc -l) )); then
        log "警告:CPU使用率过高 - ${cpu_usage}%"
        return 1
    fi
    return 0
}

# 检查内存使用率
check_mem() {
    local mem_usage=$(free -m | awk '/Mem:/ {print $3/$2 * 100.0}')
    if (( $(echo "$mem_usage > $MEM_THRESHOLD" | bc -l) )); then
        log "警告:内存使用率过高 - ${mem_usage}%"
        return 1
    fi
    return 0
}

# 检查磁盘使用率
check_disk() {
    local disk_usage=$(df -h / | awk 'NR==2 {print $5}' | tr -d '%')
    if (( disk_usage > DISK_THRESHOLD )); then
        log "警告:磁盘使用率过高 - ${disk_usage}%"
        return 1
    fi
    return 0
}

# 主监控循环
while true; do
    # 执行检查
    check_cpu || echo "CPU使用率过高,考虑扩容!"
    check_mem || echo "内存使用率过高,考虑扩容!"
    check_disk || echo "磁盘使用率过高,考虑扩容!"
    
    # 间隔60秒再次检查
    sleep 60
done

四、实现自动扩容功能

监控只是第一步,真正的价值在于能够自动响应问题。下面我们扩展脚本,加入自动扩容功能。这里以AWS EC2为例,展示如何通过AWS CLI实现自动扩容。

#!/bin/bash
# 自动扩容脚本(AWS EC2示例)
# 依赖:awscli工具(需提前配置好凭证)

# AWS配置
ASG_NAME="my-auto-scaling-group"  # 自动伸缩组名称
MAX_INSTANCES=10                  # 最大实例数
CPU_SCALE_UP_THRESHOLD=85         # CPU扩容阈值
CPU_SCALE_DOWN_THRESHOLD=30       # CPU缩容阈值
COOLDOWN_PERIOD=300               # 冷却时间(秒)
LAST_SCALE_TIME=0                 # 上次扩容时间

# 获取当前ASG信息
get_asg_info() {
    aws autoscaling describe-auto-scaling-groups \
        --auto-scaling-group-names "$ASG_NAME" \
        --query "AutoScalingGroups[0].{DesiredCapacity:DesiredCapacity, Instances:Instances}"
}

# 扩容函数
scale_up() {
    local current_time=$(date +%s)
    if (( current_time - LAST_SCALE_TIME < COOLDOWN_PERIOD )); then
        echo "仍在冷却期内,跳过扩容"
        return
    fi
    
    local asg_info=$(get_asg_info)
    local current_capacity=$(echo "$asg_info" | jq -r '.DesiredCapacity')
    
    if (( current_capacity < MAX_INSTANCES )); then
        echo "正在扩容..."
        aws autoscaling set-desired-capacity \
            --auto-scaling-group-name "$ASG_NAME" \
            --desired-capacity $((current_capacity + 1))
        LAST_SCALE_TIME=$current_time
    else
        echo "已达到最大实例数,无法继续扩容"
    fi
}

# 缩容函数
scale_down() {
    local current_time=$(date +%s)
    if (( current_time - LAST_SCALE_TIME < COOLDOWN_PERIOD )); then
        echo "仍在冷却期内,跳过缩容"
        return
    fi
    
    local asg_info=$(get_asg_info)
    local current_capacity=$(echo "$asg_info" | jq -r '.DesiredCapacity')
    
    if (( current_capacity > 1 )); then
        echo "正在缩容..."
        aws autoscaling set-desired-capacity \
            --auto-scaling-group-name "$ASG_NAME" \
            --desired-capacity $((current_capacity - 1))
        LAST_SCALE_TIME=$current_time
    else
        echo "已达到最小实例数,无法继续缩容"
    fi
}

# 主监控循环
while true; do
    # 获取当前CPU使用率
    cpu_usage=$(mpstat 1 1 | awk '/Average/ {print 100 - $NF}')
    
    # 判断是否需要扩容或缩容
    if (( $(echo "$cpu_usage > $CPU_SCALE_UP_THRESHOLD" | bc -l) )); then
        scale_up
    elif (( $(echo "$cpu_usage < $CPU_SCALE_DOWN_THRESHOLD" | bc -l) )); then
        scale_down
    fi
    
    # 间隔60秒再次检查
    sleep 60
done

五、技术细节与注意事项

  1. 精度问题
    使用mpstatfree等命令获取的资源使用率可能有1-2%的误差。对于关键业务系统,建议使用更专业的监控工具如Prometheus。

  2. 冷却期机制
    自动扩容后应该设置冷却期,避免频繁扩容缩容导致系统震荡。示例中我们设置了300秒的冷却期。

  3. 安全考虑
    自动扩容脚本通常需要较高权限。建议:

    • 使用最小权限原则
    • 通过sudoers文件精确控制权限
    • 记录所有扩容操作
  4. 多云支持
    如果需要支持多个云平台(AWS、Azure、GCP等),可以考虑使用Terraform等工具实现跨云扩容。

  5. 测试策略
    在生产环境使用前,应该:

    • 在测试环境充分验证
    • 设置手动触发开关
    • 实现优雅降级机制

六、应用场景分析

  1. 电商大促
    在618、双十一等大促期间,流量可能瞬间增长10倍以上。自动扩容可以确保网站稳定运行。

  2. 新闻热点事件
    当突发新闻事件导致流量激增时,系统可以自动扩容应对。

  3. 定时任务处理
    对于夜间运行的批量处理任务,可以在任务开始前扩容,结束后缩容,节省成本。

  4. 游戏服务器
    新游戏上线或举办活动时,玩家数量可能暴增,自动扩容确保游戏体验。

七、技术优缺点

优点

  • 响应速度快:发现问题后立即处理,无需等待人工干预
  • 节省成本:非高峰时段自动缩容,减少资源浪费
  • 提高可用性:确保系统始终有足够资源处理请求

缺点

  • 配置复杂:需要合理设置阈值和策略
  • 可能过度扩容:如果没有设置上限,可能导致不必要的开销
  • 依赖云平台API:云服务商API变更可能导致脚本失效

八、总结

通过Shell脚本实现系统资源监控与自动扩容,是一种轻量级、灵活的解决方案。虽然专业监控工具功能更强大,但Shell脚本的优势在于:

  • 无需额外软件依赖
  • 可以高度定制
  • 适合中小型系统

对于刚起步的项目或预算有限的团队,这是一个不错的起点。随着业务增长,可以逐步迁移到更专业的监控系统,如Prometheus+Grafana+Alertmanager组合。

记住,自动扩容不是银弹。它需要配合合理的容量规划、性能测试和告警机制,才能发挥最大价值。建议从简单的CPU监控开始,逐步增加内存、磁盘、网络等指标的监控,最终构建一个完整的自动化运维体系。