第2章:Linux性能工具全家桶:top、htop、vmstat、iostat、sar、perf、strace等工具的定位与使用场景

说实话,我刚入行那会儿,面对一堆性能工具是真懵。

top、htop、vmstat、iostat、sar、perf、strace……每个都能用,但到底什么时候该用哪个?

后来踩了不少坑,才慢慢摸清楚它们的脾气。今天我就把这些工具的定位和使用场景,掰开了跟你聊聊。

2.1 先搞清楚:你遇到了什么问题?

性能调优,说白了就是回答三个问题:

  • 谁在吃资源? —— CPU、内存、磁盘、网络,哪个是瓶颈?
  • 为什么吃资源? —— 是进程太多?IO太慢?还是锁竞争?
  • 怎么解决? —— 调参数、改代码、换硬件?

不同的工具,就是帮你回答不同问题的。我习惯把它们分成三类:

类别 工具 核心用途
系统概览 top、htop、vmstat 一眼看出系统整体负载
专项分析 iostat、sar 深挖磁盘、网络、历史数据
微观追踪 perf、strace 定位到函数级、系统调用级

2.2 top 和 htop:系统负载的“仪表盘”

top 是我用得最多的工具。没有之一。

每次登录服务器,第一件事就是敲 top。看什么?看 load average、CPU 使用率、内存占用。

关键指标解读:

  • load average:1分钟、5分钟、15分钟的平均负载。如果15分钟负载远高于CPU核数,说明系统一直很忙。
  • %us:用户态CPU。高的话,通常是业务进程在计算。
  • %sy:内核态CPU。高的话,可能是系统调用频繁或锁竞争。
  • %wa:等待IO。高的话,磁盘是瓶颈。

但 top 有个缺点:界面太丑,信息太密。所以后来我更喜欢用 htop

htop 支持鼠标操作,可以树状显示进程,还能直接按 F6 排序。嗯,视觉上舒服很多。

我的习惯:

日常巡检用 htop,排查问题时用 top(因为 top 默认显示的信息更全,而且很多老旧服务器没装 htop)。

2.3 vmstat:系统瓶颈的“快速扫描仪”

vmstat 是我个人非常喜欢的一个工具。它短小精悍,一行命令就能告诉你系统当前的状态。

# 每2秒输出一次,共输出5次
vmstat 2 5

输出结果里,我最关注这几列:

  • r:运行队列中的进程数。如果这个值持续大于CPU核数,说明CPU不够用。
  • b:不可中断睡眠的进程数。如果这个值高,通常是磁盘IO在等。
  • si、so:交换内存的换入换出。如果这两个值不为0,说明内存紧张,系统在频繁换页。
  • us、sy、id、wa:CPU时间分布,和 top 里的含义一样。

避坑指南:

我曾经遇到一个案例,系统负载很高,但 top 里 CPU 使用率并不高。后来用 vmstat 一看,wa 列高达 60%。原来是磁盘IO扛不住了。如果只看 top,很容易误判成CPU问题。

2.4 iostat:磁盘IO的“显微镜”

当 vmstat 告诉你 wa 很高时,就该请出 iostat 了。

# 查看磁盘IO详细情况,每2秒刷新
iostat -x 2

重点看这几个指标:

  • %util:磁盘繁忙度。接近100%说明磁盘快饱和了。
  • await:IO请求的平均等待时间(毫秒)。越高说明磁盘响应越慢。
  • svctm:IO请求的实际服务时间。如果 await 远大于 svctm,说明IO在排队。
  • r/s、w/s:每秒读写次数。结合块大小,可以估算吞吐量。

我记得有一次,数据库服务器响应很慢。用 iostat 一看,%util 只有 30%,但 await 高达 200ms。这说明磁盘本身不忙,但每个IO请求都在排队。后来发现是文件系统日志模式设置不当,改完后问题解决。

2.5 sar:系统历史的“回放机”

很多时候,问题不是实时发生的。比如半夜的告警,你早上才看到。这时候 sar 就派上用场了。

sar 会收集系统的历史数据,你可以回放任意时间点的状态。

# 查看昨天的CPU使用情况
sar -u -f /var/log/sa/sa$(date +%d -d 'yesterday')

# 查看内存使用情况
sar -r

# 查看网络流量
sar -n DEV

我的建议:

生产环境一定要开启 sar 的数据采集。默认配置通常只保留7天,我建议改成保留30天。这样排查问题时,有足够的历史数据可以回溯。

2.6 perf:CPU性能的“火焰图制造机”

当 top 告诉你某个进程CPU使用率很高,但你又不知道它在干什么时,就该 perf 出场了。

perf 可以采样CPU正在执行的指令,然后告诉你热点在哪里。

# 对PID为1234的进程采样,持续10秒
perf record -p 1234 -g -- sleep 10

# 生成火焰图数据
perf script > out.perf

# 然后用 FlameGraph 工具生成SVG火焰图

火焰图怎么看?

  • 宽度:代表该函数占用的CPU时间比例。
  • 颜色:通常红色代表内核态,黄色代表用户态。
  • 顶层:是当前正在执行的函数。
  • 底层:是调用链的根。

我曾经用 perf 定位过一个诡异的性能问题:一个Java服务CPU飙高,但jstack看线程栈全是正常状态。用 perf 一采样,发现热点在 GC 线程的某个内存拷贝函数里。后来升级了JDK版本,问题消失。

2.7 strace:系统调用的“窃听器”

strace 可以追踪进程发起的每一个系统调用。说白了,就是看你的程序在跟内核“聊什么”。

# 追踪PID为1234的进程的系统调用
strace -p 1234

# 只追踪文件操作相关的系统调用
strace -e trace=file -p 1234

# 统计系统调用的耗时
strace -c -p 1234

strace 的威力在于:它能告诉你程序为什么慢。

  • 如果看到大量的 read 调用返回很慢,说明磁盘IO是瓶颈。
  • 如果看到大量的 open 调用,说明程序在频繁打开文件。
  • 如果看到 futex 调用频繁且耗时,说明锁竞争严重。

注意:

strace 会大幅降低进程性能(可能慢10倍以上)。所以生产环境慎用,最好在测试环境复现问题后再用。

2.8 工具选择速查表

症状 首选工具 辅助工具
系统整体慢 top / htop vmstat
CPU飙高 top perf
内存不足 free -m vmstat (si/so)
磁盘IO慢 iostat strace (追踪文件操作)
网络延迟 sar -n DEV netstat / ss
进程卡死 strace gdb
历史问题回溯 sar /var/log/messages

2.9 我的工作流

最后,分享一下我排查性能问题的标准流程:

  1. 第一步:看全局 —— 用 tophtop 看系统负载,用 vmstat 看CPU和内存瓶颈。
  2. 第二步:定方向 —— 如果 wa 高,用 iostat 看磁盘;如果 us 高,用 perf 看热点。
  3. 第三步:深挖根因 —— 用 strace 追踪具体进程的系统调用,或者用 perf 生成火焰图。
  4. 第四步:验证修复 —— 改完参数或代码后,重复第一步和第二步,确认问题解决。

这套流程我用了好多年,基本覆盖了90%的性能问题。你想想看,工具再多,核心思路就这几个:先看整体,再定方向,最后深挖。

嗯,这一章就到这里。下一章我们聊聊 CPU 性能调优的具体实战。