当前位置:首页>Linux>Linux 性能诊断三板斧:从一脸懵到心中有数

Linux 性能诊断三板斧:从一脸懵到心中有数

  • 2026-10-11 06:00:30
Linux 性能诊断三板斧:从一脸懵到心中有数

CPU 飙到 100% 怎么办?磁盘 IO 慢是谁的锅?内存到底被谁吃光了?掌握 top/iostat/vmstat/strace 四件套,让你面对性能问题不再慌。

服务器又卡了?别急着重启,先用这三板斧看看谁在搞鬼。

接到报警说服务响应慢,SSH 上去一看 uptime 负载 20+,CPU 风扇嗡嗡响——这时候怎么办?

很多人的第一反应是重启。但重启只是掩盖问题,下次还会复现。今天聊一套标准诊断流程,以后遇到性能问题,按这个顺序排查就对了。

第一板斧:负载速览 — uptime + top/htop

上服务器先看三件事:谁在、负载多少、谁在吃资源。

# 1. 看负载和在线用户uptime# 输出: 16:30:45 up 30 days, 2 users, load average: 2.15, 1.80, 1.50# 2. 看进程全景top

uptime 的三个数字是 1 分钟、5 分钟、15 分钟的平均负载。这个值是等待 CPU + 等待 IO 的进程数之和,不是 CPU 使用率。很多人搞混这两个概念。

一个 4 核 CPU,负载 2.0 说明还不到一半,负载 8.0 说明已经严重过载了。

关键判断:如果负载高但 CPU 使用率低(idle 很高),说明瓶颈在 IO,不是计算——CPU 在等磁盘。

top 里重点盯这几个指标:

指标
含义
警戒线
%us
用户态 CPU
> 70% 算高
%sy
内核态 CPU
> 20% 可能驱动或系统调用有问题
%wa
IO 等待
> 10% 说明磁盘是瓶颈
%id
空闲
越低越忙
%st
被偷走的时间
虚拟机里才出现,> 5% 说明宿主机超卖

如果你用 htop,颜色就更加直观了——蓝绿是正常,红色是高负载,自己调色看着舒服。最关键的是 htop 支持鼠标点击排序和直接 F9 杀进程,比 top 顺手太多。

实战:发现 %wa 持续 30%+,%us 才 10%。说明 CPU 根本不忙,全在等磁盘。别急着找哪个进程吃 CPU,先去看 IO。

第二板斧:IO 深度分析 — iostat + iotop

确认了 IO 有问题,下一步精确定位。

# 安装: apt install sysstatiostat -x 1 3

iostat -x 的输出里,关注这几个字段:

字段
含义
怎么判断
r/sw/s
每秒读写次数
普通 SATA SSD 随机读写能到几万 IOPS,如果才几百但 CPU 在等,说明队列拥堵
rkB/swkB/s
每秒读写数据量
顺序读写 SATA SSD 能到 500MB/s,如果几十 MB/s 就到顶了,可能磁盘老化
await
平均每次 IO 等待时间
最关键指标
,SATA SSD 正常 < 5ms,> 50ms 说明严重拥堵
%util
磁盘忙碌时间占比
接近 100% 就是瓶颈。但注意 NVMe 的 %util 只看时间不看并发,可能不准
# 知道哪块盘慢了,再找哪个进程在疯狂读写iotop -o

-o 只显示有 IO 活动的进程,一眼就能看到谁在疯狂读写。

常见场景:

  1. await 爆高,r/s 不大 — 大量随机读写,比如数据库在全表扫描却没有索引,磁盘在做无用功
  2. w/s 很高,wkB/s 不大 — 大量小文件写入,比如日志疯狂刷屏没做轮转。一个 logrotate 能解决的事,别让磁盘硬扛
  3. %util 持续 100% — 磁盘真的扛不住了。短期方案:加 noatime 挂载、调大 dirty page 刷新间隔;长期方案:换 SSD 或做 RAID

第三板斧:内存追凶 — free + vmstat + smem

内存问题比 CPU 和 IO 更隐蔽,因为 Linux 的内存管理策略经常让人误判。

free -h
              total    used    free    shared  buff/cache   availableMem:           62Gi    45Gi    2.0Gi   1.0Gi        14Gi       15GiSwap:         8.0Gi    3.0Gi   5.0Gi

关键误区:free 列很小不代表内存不够——Linux 会把空闲内存拿来做缓存(buff/cache),这是好事。真正要看的是 available 列,它才是「现在有多少内存可以给新进程用」。

available 接近 0 且 swap 在增长?那就是真缺内存了。

# 看内存换入换出vmstat 1

vmstat 输出里盯这两个:

字段
含义
正常/异常
si
swap in,每秒从磁盘换入内存的量
持续 > 0 说明频繁换页,内存严重不足
so
swap out,每秒从内存换出到磁盘的量
同上,这是内存瓶颈的铁证

如果 si/so 持续非零,有两个方向:

方向一:找吃内存大户

# 按 RSS(物理内存)排序ps aux --sort=-%mem | head -20# 或者更直观的smem -t -p -s rss

smem 比 ps 好在它区分了独占内存(USS)和共享内存(PSS)——一个进程说占了 2G,可能其中有 1.5G 是共享库,实际独占只有 500M。用 USS 排序才能找到真凶。

方向二:查内存泄漏

# 看某个进程的内存趋势whiletrue; do  ps -o pid,rss,comm -p <PID> >> mem_trace.logsleep 10done

观察 RSS 是否单调增长,如果一直在涨且从不下降,大概率是内存泄漏。Java 应用常见,Go 程序相对少见但也不是没有(goroutine 泄漏)。

番外:进程行为分析 — strace/lsof

前三板斧定位了谁在吃资源,但还需要知道它在干什么。

# 看进程打开了哪些文件lsof -p <PID># 看谁在占用某个端口lsof -i :8080# 追踪系统调用strace -p <PID> -c   # 统计模式:看哪种系统调用最耗时strace -p <PID> -e trace=network  # 只看网络相关strace -p <PID> -T   # 显示每次调用的耗时

strace -c 特别实用——运行 30 秒后 Ctrl+C,它会告诉你这 30 秒里进程在干什么:

% time     seconds  usecs/call     calls    errors syscall------ ----------- ----------- --------- --------- ---------------- 99.21    5.832105        1240      4702           poll  0.45    0.026735          18      1466           read  0.22    0.012924          14       900           write

一眼看出这进程 99% 的时间在 poll 等待,说明它在等某个文件描述符就绪——可能是网络 IO 慢,也可能是管道阻塞。

诊断流程图

把这个流程固化下来,以后遇到性能问题就不用现场回想该用什么命令了:

负载告警    │    ▼uptime → 负载高吗?    │    ├─ 高 ──→ top/htop ──→ CPU 高?    │                        │    │                    ┌────┴────┐    │                    │         │    │                  us高      sy高    │                    │         │    │               ps找进程    strace    │               看业务     查系统调用    │    ├─ %wa 高 ──→ iostat ──→ iotop 找进程    │    └─ swap 活跃 ──→ free → smem 找大户 → 扩内存或杀进程

一句话总结

服务器卡了别重启,uptime → top → iostat → free → strace,五步走完原因基本就清楚了。

把这几个命令记熟,下次同事喊「服务器又挂了」的时候,你已经把根因排查出来了。那种感觉,比重启服务器爽多了。


下期预告:既然密码要记的越来越多,为什么不自己搭一个密码管理器?下期聊聊 Vaultwarden 自建方案,Bitwarden 兼容、免费、跑在自家 K3s 集群上,全家设备同步。

最新文章

随机文章