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()使用说明:
- 保存为
system_monitor.py - 安装依赖:
pip install psutil - 设置开机启动:使用
systemd创建服务 - 监控日志保存在
/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构建监控体系。
需要注意的是,频繁的系统资源监控可能会影响系统性能,建议设置合理的监控频率和数据缓存策略。同时,要严格控制监控服务的访问权限,防止潜在的安全风险。通过合理的设计和实践,可以构建出稳定可靠的系统监控体系。
评论已关闭