Shell面试题 - 请编写一个Shell脚本监控系统的CPU使用率。


引言

在系统管理和运维工作中,监控CPU使用率是一项基本而重要的任务。通过编写Shell脚本来自动化这一过程,可以帮助我们及时发现性能瓶颈,预防系统过载。本文将介绍如何使用Shell脚本监控CPU使用率,并加入流程图帮助理解整个过程。

监控CPU使用率的基本原理

CPU使用率通常通过分析/proc/stat文件或使用topmpstat等命令获取。最常用的方法是读取/proc/stat文件,它包含了系统启动以来CPU活动的累积信息。

开始监控
读取/proc/stat文件
计算CPU总时间和空闲时间
等待固定间隔
再次读取/proc/stat
计算间隔期间的CPU使用率
判断是否超过阈值
发出警报

Shell脚本实现

以下是一个基本的CPU使用率监控脚本:

#!/bin/bash

# 设置CPU使用率阈值(百分比)
THRESHOLD=80

# 监控间隔(秒)
INTERVAL=5

while true; do
    # 获取CPU使用率
    CPU_USAGE=$(top -bn1 | grep "Cpu(s)" | \
               sed "s/.*, *\([0-9.]*\)%* id.*/\1/" | \
               awk '{print 100 - $1}')
    
    # 四舍五入为整数
    CPU_USAGE=${CPU_USAGE%.*}
    
    echo "当前CPU使用率: $CPU_USAGE%"
    
    # 检查是否超过阈值
    if [ $CPU_USAGE -gt $THRESHOLD ]; then
        echo "警告: CPU使用率超过阈值 $THRESHOLD%!"
        # 这里可以添加发送警报的代码,如邮件或短信通知
    fi
    
    sleep $INTERVAL
done

Java实现示例

虽然Shell脚本更适合这种系统监控任务,但有时我们可能需要用Java来实现类似功能。以下是Java版本的CPU监控示例:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class CpuMonitor {
    private static final int THRESHOLD = 80;
    private static final int INTERVAL = 5000; // 5秒

    public static void main(String[] args) {
        try {
            while (true) {
                double cpuUsage = getCpuUsage();
                System.out.printf("当前CPU使用率: %.2f%%\n", cpuUsage);
                
                if (cpuUsage > THRESHOLD) {
                    System.out.printf("警告: CPU使用率超过阈值 %d%%!\n", THRESHOLD);
                    // 这里可以添加发送警报的代码
                }
                
                Thread.sleep(INTERVAL);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static double getCpuUsage() throws IOException, InterruptedException {
        Process process = Runtime.getRuntime().exec("top -bn1");
        try (BufferedReader reader = new BufferedReader(
                new InputStreamReader(process.getInputStream()))) {
            
            String line;
            while ((line = reader.readLine()) != null) {
                if (line.contains("Cpu(s)")) {
                    String[] parts = line.split(",");
                    String idlePart = parts[3].trim();
                    double idle = Double.parseDouble(idlePart.substring(0, idlePart.indexOf("%")));
                    return 100 - idle;
                }
            }
        }
        return 0;
    }
}

更精确的CPU监控方法

上面的方法虽然简单,但精度有限。更精确的方法是分析/proc/stat文件:

第一次读取/proc/stat
记录总时间和空闲时间
等待固定间隔
第二次读取/proc/stat
计算新的总时间和空闲时间
计算间隔期间的CPU使用率
输出结果

以下是相应的Shell脚本实现:

#!/bin/bash

INTERVAL=5
THRESHOLD=80

# 获取CPU时间函数
get_cpu_time() {
    read -r cpu user nice system idle iowait irq softirq steal guest guest_nice < /proc/stat
    total=$((user + nice + system + idle + iowait + irq + softirq + steal))
    echo "$total $idle"
}

# 第一次读取
read total1 idle1 < <(get_cpu_time)
sleep $INTERVAL

while true; do
    # 第二次读取
    read total2 idle2 < <(get_cpu_time)
    
    # 计算差值
    total=$((total2 - total1))
    idle=$((idle2 - idle1))
    
    # 计算使用率
    usage=$((100 * (total - idle) / total))
    
    echo "CPU使用率: $usage%"
    
    # 检查阈值
    if [ $usage -gt $THRESHOLD ]; then
        echo "警告: CPU使用率超过 $THRESHOLD%!"
    fi
    
    # 更新上一次的值
    total1=$total2
    idle1=$idle2
    
    sleep $INTERVAL
done

监控脚本的增强功能

一个完善的监控脚本还应该包含以下功能:

  1. 日志记录:将监控结果写入日志文件
  2. 警报通知:通过邮件、短信或API发送警报
  3. 历史数据分析:记录历史数据用于趋势分析
  4. 进程级监控:识别消耗CPU资源最多的进程
CPU监控脚本
基础监控
日志记录
警报通知
历史数据分析
进程级监控
定期检查CPU使用率
写入日志文件
邮件/短信/API通知
生成趋势报告
识别高CPU进程

总结

通过Shell脚本监控CPU使用率是系统管理中的一项基本技能。本文介绍了多种实现方法,从简单的top命令解析到更精确的/proc/stat分析方法。我们还展示了如何用Java实现类似功能,并通过流程图帮助理解监控过程。

在实际应用中,可以根据需求扩展脚本功能,如添加日志记录、警报通知等,以构建一个完整的系统监控解决方案。

Logo

技术共进,成长同行——讯飞AI开发者社区

更多推荐