Linux--07---查看CPU、内存、磁盘

'# Linux--07---查看CPU、内存、磁盘

一、背景与问题

在Linux系统中,资源监控是系统运维和性能调优的核心任务。开发者和运维人员需要实时了解CPU、内存、磁盘的使用情况,以排查性能瓶颈、优化系统配置或防止资源耗尽导致的系统崩溃。

传统方法依赖top、free、iostat等命令行工具,但这些工具的底层实现机制和数据采集方式对理解系统运行状态至关重要。本文将深入解析这些工具的原理,结合实际开发场景说明其使用场景和注意事项。

二、基本原理

Linux系统通过虚拟文件系统(/proc)和sysfs(/sys)提供丰富的系统资源信息。这些虚拟文件系统将内核状态暴露给用户空间,供监控工具读取。

1. CPU监控原理

CPU信息主要来源于/proc/stat文件,其中包含以下关键字段:

  • cpu:所有CPU的累计统计(用户态、内核态、空闲等)
  • cpu0、cpu1等:每个物理CPU的统计
  • cpuinfo:详细CPU架构信息(型号、核心数、线程数等)

2. 内存监控原理

内存信息主要来源于/proc/meminfo文件,包含:

  • MemTotal:总内存
  • MemFree:空闲内存
  • Buffers:缓冲区占用
  • Cached:缓存占用
  • SwapTotal:交换分区总容量

3. 磁盘监控原理

磁盘IO信息主要来源于:

  • iostat工具:通过/proc/diskstats读取每个磁盘的读写统计
  • df命令:通过/etc/mtab读取文件系统挂载点信息
  • lsblk:通过/sys/block读取块设备信息

三、环境准备

确保系统中安装必要工具:

# 安装sysstat工具(iostat、iostat等)
sudo apt install sysstat -y  # Debian/Ubuntu
sudo yum install sysstat -y  # CentOS/RHEL

# 安装psutil库(Python监控)
pip install psutil

四、核心实现

1. 基础命令行工具

(1) 查看CPU使用率(top)

top -b -n 1 | grep "Cpu(s)"

原理:top通过读取/proc/stat计算CPU使用率,Cpu(s)行显示用户态、系统态、空闲等占用比例。

(2) 查看内存使用情况(free)

free -h

原理:free解析/proc/meminfo,将内存单位转换为可读格式,显示total、used、free等指标。

(3) 查看磁盘IO(iostat)

iostat -d 1 3

原理:iostat读取/proc/diskstats,计算每个磁盘的读/写次数、数据量等指标,-d参数仅显示磁盘统计。

2. Python实现的监控脚本

import psutil
import time

def monitor_system():
    while True:
        # CPU监控
        cpu_percent = psutil.cpu_percent(interval=1)
        print(f"CPU Usage: {cpu_percent}%")
        
        # 内存监控
        mem = psutil.virtual_memory()
        print(f"Memory: {mem.percent}% ({mem.used / 1024**3:.2f}GB)")
        
        # 磁盘监控
        disk = psutil.disk_usage('/')
        print(f"Disk: {disk.percent}% ({disk.used / 1024**3:.2f}GB)")
        
        # 网络监控
        net = psutil.net_io_counters()
        print(f"Network: {net.bytes_sent / 1024**2:.2f}MB sent")
        
        time.sleep(5)

if __name__ == "__main__":
    monitor_system()

关键代码解释:

  • psutil.cpu_percent():通过读取/proc/stat计算CPU使用率
  • psutil.virtual_memory():解析/proc/meminfo获取内存信息
  • psutil.disk_usage():通过/etc/mtab获取文件系统信息

3. 自定义监控工具(C语言实现)

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

int main() {
    int fd;
    char buf[1024];
    
    // 读取CPU信息
    fd = open("/proc/stat", O_RDONLY);
    read(fd, buf, sizeof(buf));
    printf("CPU Usage: %s\n", buf);
    close(fd);
    
    // 读取内存信息
    fd = open("/proc/meminfo", O_RDONLY);
    read(fd, buf, sizeof(buf));
    printf("Memory Info: %s\n", buf);
    close(fd);
    
    // 读取磁盘信息
    fd = open("/proc/diskstats", O_RDONLY);
    read(fd, buf, sizeof(buf));
    printf("Disk Stats: %s\n", buf);
    close(fd);
    
    return 0;
}

关键代码解释:

  • 通过open()系统调用直接读取虚拟文件系统
  • /proc/stat包含累计统计信息,需要通过计算获取实时数据
  • /proc/diskstats记录每个磁盘的IO统计

五、完整案例

1. 系统监控服务(Python实现)

# system_monitor.py
import psutil
import time
import logging
from datetime import datetime

# 配置日志
logging.basicConfig(filename='/var/log/system_monitor.log', 
                    level=logging.INFO,
                    format='%(asctime)s - %(message)s')

def monitor_system():
    while True:
        try:
            # CPU监控
            cpu_percent = psutil.cpu_percent(interval=1)
            logging.info(f"[{datetime.now()}] CPU Usage: {cpu_percent}%")
            
            # 内存监控
            mem = psutil.virtual_memory()
            logging.info(f"[{datetime.now()}] Memory: {mem.percent}% ({mem.used / 1024**3:.2f}GB)")
            
            # 磁盘监控
            disk = psutil.disk_usage('/')
            logging.info(f"[{datetime.now()}] Disk: {disk.percent}% ({disk.used / 1024**3:.2f}GB)")
            
            # 网络监控
            net = psutil.net_io_counters()
            logging.info(f"[{datetime.now()}] Network: {net.bytes_sent / 1024**2:.2f}MB sent")
            
        except Exception as e:
            logging.error(f"[{datetime.now()}] Error: {str(e)}")
        
        time.sleep(5)

if __name__ == "__main__":
    monitor_system()

使用说明:

  1. 保存为system_monitor.py
  2. 安装依赖:pip install psutil
  3. 设置开机启动:使用systemd创建服务
  4. 监控日志保存在/var/log/system_monitor.log

性能优化建议:

  • 使用缓存机制避免频繁读取/proc文件
  • 使用多线程处理不同监控指标
  • 使用fallocate预分配日志文件空间

六、源码解析

以iostat工具为例,其核心代码逻辑如下(简化版):

#include <stdio.h>
#include <sys/sysinfo.h>

int main() {
    struct sysinfo sys;
    sysinfo(&sys);
    
    printf("CPU Usage: %.2f%%\n", sys.loads[0] * 100.0 / sys.totalram);
    printf("Memory Usage: %.2f%%\n", sys.memused * 100.0 / sys.totalram);
    printf("Disk I/O: %d reads, %d writes\n", sys.loads[1], sys.loads[2]);
    
    return 0;
}

关键点:

  • sysinfo()系统调用获取全局系统状态
  • sys.loads数组包含CPU负载信息
  • sys.memused表示内存使用量

七、进阶使用

1. 实时监控可视化

import matplotlib.pyplot as plt
import numpy as np
from matplotlib.animation import FuncAnimation

def update(frame):
    cpu = psutil.cpu_percent(interval=0.1)
    mem = psutil.virtual_memory().percent
    disk = psutil.disk_usage('/').percent
    
    line1.set_ydata([cpu])
    line2.set_ydata([mem])
    line3.set_ydata([disk])
    
    return line1, line2, line3

fig, (ax1, ax2, ax3) = plt.subplots(3, 1, sharex=True)
line1, = ax1.plot([], [], lw=2)
line2, = ax2.plot([], [], lw=2)
line3, = ax3.plot([], [], lw=2)

ani = FuncAnimation(fig, update, interval=1000, blit=True)
plt.show()

应用场景:

  • 前端开发中用于实时性能监控
  • 云服务监控仪表盘
  • 容器化环境的资源可视化

2. 基于Prometheus的监控集成

from prometheus_client import start_http_server, Gauge
import psutil

CPU_USAGE = Gauge('cpu_usage_percent', 'CPU usage in percent')
MEMORY_USAGE = Gauge('memory_usage_percent', 'Memory usage in percent')
DISK_USAGE = Gauge('disk_usage_percent', 'Disk usage in percent')

def update_metrics():
    CPU_USAGE.set(psutil.cpu_percent(interval=1))
    MEMORY_USAGE.set(psutil.virtual_memory().percent)
    DISK_USAGE.set(psutil.disk_usage('/').percent)

if __name__ == '__main__':
    start_http_server(8000)
    while True:
        update_metrics()
        time.sleep(5)

优势:

  • 支持Prometheus监控系统
  • 可集成到Grafana进行可视化
  • 支持自动发现和告警

八、性能与工程实践

1. 性能优化策略

优化点方法效果
避免频繁读取使用缓存减少I/O次数
减少计算开销预计算降低CPU占用
避免竞争串行化防止并发冲突
优化日志压缩日志减少磁盘IO

2. 异常处理设计

def safe_read(path):
    try:
        with open(path, 'r') as f:
            return f.read()
    except Exception as e:
        logging.warning(f"Failed to read {path}: {str(e)}")
        return None

注意事项:

  • 处理文件不存在、权限不足等异常
  • 设置合理的重试机制
  • 确保监控服务的高可用性

3. 安全风险分析

风险点影响解决方案
权限不足无法读取敏感信息设置适当权限
拒绝服务被恶意监控限制访问频率
数据泄露暴露系统状态加密敏感信息
SQL注入无不存在SQL注入风险

九、常见问题与踩坑

1. 常见错误及解决办法

错误原因解决方法
Permission denied权限不足使用sudo或调整权限
No such file or directory文件不存在检查文件路径
Resource temporarily unavailable系统资源不足增加资源或优化程序
Segmentation fault内存越界检查指针使用

2. 常见错误示例

# 错误示例:未处理异常
def bad_monitor():
    with open('/proc/stat', 'r') as f:
        print(f.read())

# 正确示例:异常处理
def safe_monitor():
    try:
        with open('/proc/stat', 'r') as f:
            print(f.read())
    except Exception as e:
        print(f"Error: {str(e)}")

改进说明:

  • 增加异常处理机制
  • 添加日志记录
  • 设置合理的错误恢复策略

十、最佳实践

1. 推荐方案

场景推荐方案说明
基础监控top/free快速查看
精确监控iostat磁盘IO分析
程序监控psutil跨平台开发
可视化监控Grafana实时图表展示
集成监控Prometheus系统监控体系

2. 推荐开发规范

  • 使用/proc文件系统时注意文件描述符管理
  • 对关键指标进行缓存(缓存时间建议5-10秒)
  • 对监控数据进行归一化处理
  • 对异常情况设置阈值告警

十一、总结

Linux系统资源监控是一个既基础又复杂的领域。通过深入理解/proc文件系统、sysfs等虚拟文件系统的原理,开发者可以构建出高效可靠的监控系统。本文从基础命令行工具到高级开发实践,展示了多种实现方式,并深入分析了性能优化、安全风险和常见问题。

在实际项目中,推荐使用psutil等封装库进行开发,以提高开发效率和代码可维护性。同时,需要根据具体业务场景选择合适的监控方案:对于简单的资源查看,使用top/free即可;对于复杂的性能调优,建议结合Prometheus和Grafana构建监控体系。

需要注意的是,频繁的系统资源监控可能会影响系统性能,建议设置合理的监控频率和数据缓存策略。同时,要严格控制监控服务的访问权限,防止潜在的安全风险。通过合理的设计和实践,可以构建出稳定可靠的系统监控体系。

最后修改于:2026年10月06日 09:25

评论已关闭

推荐阅读

AIGC实战——Transformer模型
2024年12月01日
Socket TCP 和 UDP 编程基础(Python)
2024年11月30日
python , tcp , udp
如何使用 ChatGPT 进行学术润色?你需要这些指令
2024年12月01日
AI
最新 Python 调用 OpenAi 详细教程实现问答、图像合成、图像理解、语音合成、语音识别(详细教程)
2024年11月24日
ChatGPT 和 DALL·E 2 配合生成故事绘本
2024年12月01日
omegaconf,一个超强的 Python 库!
2024年11月24日
【视觉AIGC识别】误差特征、人脸伪造检测、其他类型假图检测
2024年12月01日
[超级详细]如何在深度学习训练模型过程中使用 GPU 加速
2024年11月29日
Python 物理引擎pymunk最完整教程
2024年11月27日
MediaPipe 人体姿态与手指关键点检测教程
2024年11月27日
深入了解 Taipy:Python 打造 Web 应用的全面教程
2024年11月26日
基于Transformer的时间序列预测模型
2024年11月25日
Python在金融大数据分析中的AI应用(股价分析、量化交易)实战
2024年11月25日
AIGC Gradio系列学习教程之Components
2024年12月01日
Python3 `asyncio` — 异步 I/O,事件循环和并发工具
2024年11月30日
llama-factory SFT系列教程:大模型在自定义数据集 LoRA 训练与部署
2024年12月01日
Python 多线程和多进程用法
2024年11月24日
Python socket详解,全网最全教程
2024年11月27日
python之plot()和subplot()画图
2024年11月26日
理解 DALL·E 2、Stable Diffusion 和 Midjourney 工作原理
2024年12月01日