Linux 排障六条命令:top、vmstat、iostat、ss、free、df 各看哪一行,按什么顺序打
机器变慢时最浪费时间的动作是打开 top 盯着看。六条命令里有两条能在五秒内排除掉整类故障,另外四条用来做归因。我习惯的顺序是 df -h → free -m → top -bn1 → vmstat 1 5 → iostat -x 1 5 → ss -s:先排除磁盘写满和内存耗尽这两种一眼可见的硬故障,再判断是 CPU 排队、IO 等待还是连接堆积。下面把每条命令该看哪一行、阈值大概在哪、以及容易读错的地方列清楚。
每条命令看哪一个字段
| 顺序 | 命令 | 一眼要看的字段 | 判读 | 常见误读 |
|---|---|---|---|---|
| 1 | df -h | Use%、Avail | 任一挂载点接近 100% 就先处理磁盘,别继续看 CPU | 只看 /,漏掉 /var、/var/lib/docker 单独挂载 |
| 2 | free -m | available | available 接近 0 且 si/so 非零才是真内存压力 | 把 free 列当可用内存,页缓存被当成"被吃掉" |
| 3 | top -bn1 | load average、%Cpu 的 wa、Tasks 的 D | wa 高是 IO 等待;D 状态任务多说明卡在磁盘 | 用单次快照判断瞬时负载,-bn1 只是一帧 |
| 4 | vmstat 1 5 | r、b、si、so、wa | r 持续大于核数是 CPU 排队;b 大于 0 是阻塞在 IO | 误读第一行(开机以来平均值) |
| 5 | iostat -x 1 5 | %util、await、aqu-sz | await 明显上升 + %util 接近 100 才是设备饱和 | 把 SSD/RAID 的 %util 当作性能上限 |
| 6 | ss -s | TCP: estab、timewait、closed | closed 堆积常见于端口耗尽或短连接风暴 | 用 netstat 的旧习惯读,或忘了 ss 默认不列监听口 |
可以直接抄的六条:
df -h; df -i # 空间 + inode 两个维度
free -m # available 才是可用量
top -bn1 | head -12 # 一帧快照,看 load / wa / D 态
vmstat 1 5 # 从第二行开始才是这 5 秒的采样
iostat -x 1 5 # 设备级 await / aqu-sz / %util
ss -s; ss -tlnp # 汇总 + 谁在监听
在本机 Debian 12 容器(32 核宿主、Docker Desktop 29.4.3)里跑出来的样子,可以作为格式参照:
$ nproc
32
$ free -m
total used free shared buff/cache available
Mem: 31901 1360 30145 11 764 30541
$ df -h /
Filesystem Size Used Avail Use% Mounted on
overlay 1007G 18G 938G 2% /
$ ss -s
Total: 1
TCP: 51 (estab 0, closed 51, orphaned 0, timewait 1)
这组输出本身很"安静":load average 0.37、wa 0、r 等于 1、si/so 全零、设备 %util 全零。安静不等于没用,它排除了一整片区域——内存没有换页、设备没有排队、CPU 没有等 IO。剩下的怀疑对象就只有"进程自己在算"和"上游在等"两类,这时候再去看 pidstat 1 挑进程、看应用日志挑调用,比继续盯着 top 有效。
把这六条读成一条链:df 与 free 是准入检查,top 给方向(CPU 还是 IO),vmstat 给证据(r/b 分布),iostat 给设备级定位,ss 把视角切到网络侧。任何一步出现明确的异常信号就停下来处理,不要为了"跑全"而继续往下打。
四个容易读错的地方
第一,vmstat 的第一个数据行不是当前状态。手册写得很直接:第一条报告给出的是自上次重启以来的平均值,只有后续报告才是 delay 长度的采样。所以 vmstat 1 5 要看第 2 行到第 6 行。同理 iostat 的首份报告也是开机以来的累计,-y 参数就是用来跳过它的。
第二,free 的 free 列不是可用内存。可用量看 available,它把可回收的页缓存和 slab 算了进去;used 的定义也是 total - available。本机这组数据里 free 是 30145 MiB、buff/cache 只有 764 MiB,两个数字都对,但判断"还能不能起新进程"要用 available 的 30541 MiB。
第三,top 的 %CPU 在多核机器上会超过 100%。一个多线程进程在非线程模式下可能显示 300%,这不是异常,是"占用了三个核"的意思;I 键可以在 Irix 与 Solaris 两种口径之间切换,后者会把百分比除以核数。看到 200% 就去报警,是把口径当成了故障。
第四,容器里读到的很多是宿主口径。这点值得单独说:在 debian:12-slim 容器里 iostat -x 直接列出了宿主机的 sda、sdb、loop0,%util 全是 0;nproc 返回 32,也是宿主核数;top 的 MiB Mem 是宿主内存。容器没有自己的块设备视图,这些数字不能用来判断"这个容器 IO 高"。要定位容器,用 cgroup 的 cpu.stat、memory.current、io.stat,或者直接在宿主上看。
小结
六条命令的价值不在于全跑一遍,而在于每条只回答一个问题:磁盘还有没有空间、内存是否真的不够、CPU 是在算还是在等、设备是否饱和、连接是否堆住。把顺序固定下来,就不会在 top 里迷路,也不会把页缓存当成内存泄漏。真正需要连续观察时,用 vmstat 1、iostat -x 1、pidstat 1 这类带间隔的形式看趋势,单帧快照只适合确认"现在有没有"。
排障记录里建议把命令和当时的输出一起留下。同样的 await,在空载和满载下含义完全不同;没有原始数字,事后无法复核判断是否成立。容器场景再补一句口径说明:宿主指标和容器指标分开记,别混在一张表里。
如果六条跑完都没有异常,下一步不是继续加命令,而是换视角:看应用侧的耗时分布(慢日志、trace),看是否被限流(cgroup 的 cpu.max、memory.max),看是否在等外部依赖(DNS、数据库、对象存储)。六条命令能证明"这台机器本身没有明显瓶颈",这已经是很强的结论,剩下的事情通常在机器之外。
数据来源与检索时间
| 来源 | URL | 对应数据 |
|---|---|---|
| man7.org · top(1) | https://man7.org/linux/man-pages/man1/top.1.html | %CPU 可超 100%、Irix/Solaris 口径、summary 区 wa/st 含义 |
| man7.org · vmstat(8) | https://man7.org/linux/man-pages/man8/vmstat.8.html | 第一份报告为开机以来平均值;r/b/si/so/wa 字段定义 |
| man7.org · iostat(1) | https://man7.org/linux/man-pages/man1/iostat.1.html | await、aqu-sz、%util 定义;-y 跳过首份报告 |
| man7.org · free(1) | https://man7.org/linux/man-pages/man1/free.1.html | available 与 used = total - available 的定义 |
| man7.org · ss(8) | https://man7.org/linux/man-pages/man8/ss.8.html | -s 汇总、-l 监听口、-p 进程、-o 定时器 |
| man7.org · df(1) | https://man7.org/linux/man-pages/man1/df.1.html | -i 列 inode、-h 人类可读、--output 字段选择 |
检索时间:2026-11-10(Asia/Shanghai)。
核验说明
- 真跑:文中所有命令输出均在
debian:12-slim容器内执行(Docker Desktop 29.4.3,未映射宿主端口),包括nproc、free -m、df -h、df -i、ss -s、top -bn1、vmstat 1 3、iostat -x 1 2。文中引用的数值为该次运行的原始输出。 - 真跑:容器内
iostat列出宿主sda/sdb/loop0与nproc=32属实测观察,不是推断。 - 仅依据文档:
%CPU超过 100% 的具体显示、Irix/Solaris 切换效果未构造多线程负载验证;iostat的-y与%util在 SSD 上的失真程度未实测,按手册描述记录。 - 未验证:跨挂载点的
df遗漏场景(/var/lib/docker独立挂载)属常见现象,文中未在本机构造该布局。