如果你去问一位老运维,Linux 上最值得花时间吃透的东西是什么,十有八九不是某个花哨的配置,而是资源管理命令。它们平时安静地躺在 /usr/bin 里,一旦线上出问题,就是你能不能在一小时内定位根因的底气。我这些年见过太多同事查故障时只会反复敲 top,看到负载高就发蒙,最后恨不得重启机器。今天我把自己多年压箱底的这套命令和思路整理出来,包括 CPU、内存、磁盘IO、网络四类核心资源的观测方法,最后会用一个真实故障串起整个排查流程。无论你是刚转行后台的实习生,还是已经写了三年脚本的运维老兵,这篇文章都值得你从头看一遍。
1. 观测CPU与负载:从top开始,但不能只看top
在资源管理命令里,top 是多数人第一个接触的。真正理解它的输出,需要区分几个数字,否则很容易被表面的高负载带走。
1.1 top 输出里被误读最多的几个数字
top 第一行有三个 load average:1分钟、5分钟、15分钟的平均负载。很多人以为超过1就是满负载,这个观念在单核时代成立,在现在多核机器上完全不成立。负载是处于可运行状态和不可中断状态的平均进程数。4核 CPU 上 load average 为4,大致相当于把每个核心排队占满。所以判断负载时,要除以逻辑核心数,而不是盯着绝对值。
CPU 这一行中,us 是用户态 CPU 时间,sy 是内核态时间,ni 是 nice 调整后的低优先级时间,id 是空闲,wa 是等待 IO 的时间,hi 和 si 分别指硬中断和软中断,st 是虚拟化环境下被其他虚拟机抢占的时间。其中 wa 高说明 CPU 在等 IO 返回,但这并不等于一定是磁盘坏了,也可能是内存交换、网络存储延迟,甚至是一个挂载不正常的 NFS 目录。
这里有个常见误区:负载高就以为是 CPU 不够用。真实场景里,CPU 使用率可能很低,但 load 已经很高,因为很多进程被阻塞在了 IO 上。只看 %CPU 不看整行状态,很容易误判成扩容,白花成本。
1.2 负载高、CPU却不高的陷阱:不可中断进程与 vmstat
真实排障中常出现:uptime 显示 load 已经到 20,top 里 CPU 的 us 却只有 10%,id 也不是很高。这时要看有多少进程处于 D 状态(不可中断睡眠,通常是等待 IO)。top 状态栏的 D 进程如果长期存在,说明 IO 栈的下游没有返回。
vmstat 1 可以把这个局面打开。第一行是开机以来的平均值,后面的行才是最近1秒的实时数据。重点看以下字段:
r:运行队列长度,持续大于 CPU 核心数说明 CPU 算力吃紧。b:不可中断睡眠进程数,长期非零说明 IO 等待真实存在。wa:CPU 等待 IO 的时间百分比。si/so:换入换出页面数,长期非零说明内存压力已经传导到 swap。
一个我踩过的例子:某台业务机 load 很高,但 top 里 us、sy 都不高,wa 60%,D 状态进程三四个。我当时第一反应是磁盘故障,结果 iostat 显示某块云盘的 %util 只有 20%。后来发现是 NFS 挂载目录的一个客户端一直重试访问,网络文件系统的超时把进程拖在 D 状态。vmstat 只告诉我们“有人在等 IO”,但具体等哪个设备,需要 iostat 和进程栈一起看。
1.3 用 pidstat 和 mpstat 把定位细化到线程
top 默认只看到进程级,多线程应用光看进程级不够。pidstat -p <pid> 1 可以按进程输出 CPU 使用率;配合 -t 参数能看到每个线程。用 top -H -p <pid> 也能看线程,但 pidstat 的输出更适合脚本和时间序列分析。
mpstat -P ALL 1 会把每个 CPU 核心的使用情况单独打出来。多核机器上如果只有某一个核跑满,而其他核闲置,通常不是整体性能不够,而是单线程热点,要顺着线程找到代码里的热点。
组合用法:先用 top -H -p <pid> 找到 CPU 占用最高的
