系统级监控:top、htop、vmstat、iostat、sar 等工具的使用与解读
说实话,很多 C 程序员调试性能时,第一反应就是掏出 perf 或者 gprof。这没错,但有点「捡了芝麻丢了西瓜」。你想想看,如果整个系统都在喘气,CPU 在打架、内存在爆缸、磁盘在哀嚎,你光盯着自己那几行代码有什么用?
我个人习惯是:先看系统,再看进程,最后看代码。系统级监控就是你的第一道防线。今天我就带你把这几个看家工具捋一遍。
核心思路:系统级监控不是让你看热闹,而是帮你快速定位瓶颈在哪个子系统——CPU、内存、磁盘 I/O 还是网络。
1. top:最朴素的「系统体检仪」
top 是我用得最多的工具,没有之一。它就像医院的体温计,一眼就能看出系统是不是在发烧。
运行 top 后,你会看到两大部分:系统概况和进程列表。
系统概况区
| 指标 | 含义 | 我关注的阈值 |
|---|---|---|
| load average | 1分钟、5分钟、15分钟的平均负载 | 超过 CPU 核心数的 70% 就要警惕 |
| %us | 用户态 CPU 占用 | 持续 > 80% 说明计算密集 |
| %sy | 内核态 CPU 占用 | > 20% 可能系统调用过多 |
| %wa | 等待 I/O 的 CPU 时间 | > 30% 磁盘大概率是瓶颈 |
| %id | CPU 空闲率 | 接近 0% 说明 CPU 吃满了 |
我的小技巧:按 1 键可以展开每个 CPU 核心的使用情况。我曾经遇到过一个 32 核的机器,整体负载不高,但某个核心跑到了 100%,结果是一个单线程的 C 程序在死循环。按 1 一眼就揪出来了。
进程列表区
重点关注 %CPU、%MEM 和 RES(常驻内存)。我一般按 P 键按 CPU 排序,按 M 键按内存排序。
# 常用快捷键
top - 按 'P' 按 CPU 排序
top - 按 'M' 按内存排序
top - 按 'k' 杀掉进程
top - 按 'r' 调整优先级(nice 值)
2. htop:top 的「可视化升级版」
htop 说白了就是 top 的图形化增强版。它支持鼠标操作,颜色更丰富,还能横向滚动看完整命令行。
我个人更喜欢 htop 的一点是:它把进程树显示得很清楚。你按 F5 就能看到父子进程关系。有一次我排查一个内存泄漏,发现一个父进程 fork 了上百个子进程,每个都在吃内存,htop 的树形视图让我秒懂问题所在。
# 安装 htop
sudo apt install htop # Ubuntu/Debian
sudo yum install htop # CentOS/RHEL
# 常用操作
F2 - 设置界面(可以调整显示列)
F3 - 搜索进程
F4 - 过滤进程
F5 - 树形视图
F6 - 排序选择
注意:htop 虽然好看,但它在某些嵌入式环境或最小化安装的系统中可能没有。我建议你至少把 top 玩熟,htop 当作锦上添花。
3. vmstat:系统整体「健康报告」
vmstat 是我排查性能问题时第二个必用的工具。它不像 top 那样持续刷新,而是给你一个快照式的系统状态。
# 每隔 1 秒输出一次,共输出 5 次
vmstat 1 5
输出结果中,我重点关注这几列:
| 列名 | 含义 | 危险信号 |
|---|---|---|
| r | 正在运行的进程数(不包括等待 I/O 的) | 持续 > CPU 核心数,说明 CPU 饱和 |
| b | 不可中断睡眠的进程数(通常是在等 I/O) | > 0 且持续增长,磁盘 I/O 可能有问题 |
| swpd | 已使用的交换空间 | > 0 且持续增长,内存不足 |
| si / so | 从磁盘交换入/出的内存量 | 持续 > 0,内存严重不足 |
| us / sy | 用户态/内核态 CPU 时间 | 同 top 的解读 |
| wa | 等待 I/O 的时间 | > 30% 基本可以断定 I/O 瓶颈 |
实战经验:我曾经接手过一个 C 语言写的网关程序,用户反馈「偶尔卡死」。我上去跑了个 vmstat 1,发现 b 列每隔几十秒就跳到 10 以上,wa 飙到 60%。顺藤摸瓜,发现是日志写入磁盘时锁竞争导致的。把同步写改成异步写,问题解决。
4. iostat:磁盘 I/O 的「显微镜」
当 vmstat 告诉你 wa 很高时,下一步就是用 iostat 看看到底是哪块磁盘在拖后腿。
# 查看所有磁盘的 I/O 统计,每 2 秒刷新一次
iostat -x 2
# 只看某个磁盘(比如 sda)
iostat -x sda 2
输出中,我盯死这几个指标:
| 指标 | 含义 | 我的经验值 |
|---|---|---|
| %util | 磁盘忙绿百分比 | > 80% 说明磁盘接近饱和 |
| await | I/O 请求的平均等待时间(毫秒) | 机械盘 > 20ms 有问题,SSD > 5ms 有问题 |
| svctm | I/O 请求的平均服务时间(毫秒) | 如果远小于 await,说明排队严重 |
| r/s / w/s | 每秒读/写请求数 | 结合 await 看,请求多且慢就是瓶颈 |
避坑指南:我曾经遇到过一个案例,%util 只有 30%,但程序就是慢。后来发现是 r/s 和 w/s 极高,但每次读写的数据量很小——典型的「小文件频繁读写」问题。%util 低不代表没问题,要综合看。
5. sar:历史数据的「回放机」
sar 是 sysstat 包里的工具,它的最大价值在于:可以查看过去一段时间系统的状态。你不可能 24 小时盯着终端,但 sar 可以帮你记录。
# 查看今天的 CPU 使用情况
sar -u
# 查看今天的内存使用情况
sar -r
# 查看今天的磁盘 I/O
sar -d
# 查看特定时间段的记录(比如 10:00 到 11:00)
sar -u -s 10:00:00 -e 11:00:00
sar 的数据来源是 /var/log/sysstat/ 目录下的历史文件。默认每 10 分钟采集一次。
我的用法:用户报障说「昨天下午系统很慢」,我直接 sar -u -s 14:00 -e 16:00,看到 CPU 在 15:30 左右突然飙高,再配合 sar -r 发现内存也在那个时间点吃紧。一查 crontab,发现那个时间点有个定时任务在跑一个 C 程序的全量数据加载。调整任务时间,问题解决。
6. 工具选择流程图
下面这张图是我自己总结的排查思路,你可以照着走一遍:
7. 组合拳:一个真实案例
光讲工具没意思,我分享一个我去年遇到的案例。
一个 C 语言写的视频转码服务,用户反馈「转码越来越慢,最后卡死」。我按顺序排查:
- top 一看:CPU 占用不高,但
wa高达 50%。嗯,磁盘有问题。 - vmstat 确认:
b列有 5-8 个进程在等 I/O,si/so不为 0。内存也在告急。 - iostat -x 1:
%util接近 100%,await超过 100ms。磁盘确实在满负荷运转。 - sar -r -s 09:00 -e 10:00:发现内存从 09:30 开始被大量占用,swap 开始增长。
最终定位:转码程序在处理大文件时,内存分配策略有问题,导致频繁 swap,进而引发磁盘 I/O 风暴。修复后,wa 降到 5% 以下。
记住:工具只是你的眼睛,真正重要的是分析思路。不要被某个指标牵着鼻子走,要交叉验证。
8. 总结一下
系统级监控说白了就是四个字:由粗到细。top 看全局,vmstat 看子系统,iostat 看磁盘,sar 看历史。每一步都在缩小排查范围。
我个人建议你把这几个工具练到「肌肉记忆」的程度。遇到性能问题,不要急着翻代码,先跑一轮系统监控。很多时候,问题根本不在你的代码里,而在系统层面。
嗯,工具就讲到这里。下次你遇到系统卡顿,知道该先敲哪个命令了吧?