跳到主要内容
约 8 分钟3 张卡

Linux 性能排查

线上机器变慢时,排查的顺序是先看整体资源(CPU、内存、磁盘 I/O、网络)哪一项饱和,再定位到进程,最后定位到进程里的线程或代码。本文讲 load average 的含义、几个常用工具的关键字段,以及“CPU 高”“系统卡”“CPU 不高但接口慢”三类场景的排查路径。具体到 Java 进程的线程和代码定位见 Java CPU 飙高排查。

1. 面试核心​

先记住这几条,再读正文
  • load average 是 1、5、15 分钟内处于可运行(R)和不可中断睡眠(D,通常在等磁盘 I/O)状态的平均进程数,不是 CPU 使用率。要和 CPU 核数比较:持续高于核数说明有任务在排队。卡 · load average
  • load 高不一定是 CPU 忙:大量进程在等 I/O 时 load 也会升高,而 CPU 使用率很低。用 top 的 us/sy/wa 和 vmstat 的 r/b 区分。
  • CPU 使用率高的排查链路:top 找进程 → top -Hp 或 pidstat -t 找线程 → perf top、jstack 等找到代码;同时区分用户态(业务计算)和内核态(系统调用、中断、上下文切换)。卡 · 三类场景的排查路径
  • CPU 不高但接口慢,瓶颈在等待:磁盘 I/O、网络与下游依赖、锁、连接池或线程池耗尽、内存不足导致的交换。按“机器资源 → 网络 → 应用内部 → 下游”的顺序逐项排除。卡 · 三类场景的排查路径
  • 先看趋势再看快照:对比问题前后的监控曲线,确认是突增还是缓慢增长,以及是否与发布、流量变化同时发生。

2. load average​

uptime 和 top 第一行显示三个数,分别是 1、5、15 分钟的指数加权平均负载。Linux 的负载统计两类进程:

  • R:正在运行或在运行队列中等待 CPU。
  • D:不可中断睡眠,通常在等待磁盘 I/O,也可能在等 NFS 或某些内核锁。

判断方法:

情况含义
负载 < 核数CPU 有空闲
负载 ≈ 核数CPU 刚好用满
负载持续 > 核数有任务在排队;再看是 CPU 忙还是 I/O 等待
1 分钟值远高于 15 分钟值负载正在上升,问题刚发生
1 分钟值远低于 15 分钟值负载在回落

核数用 nproc 或 lscpu 查看。负载高的常见原因:计算密集的进程、大量线程竞争 CPU、磁盘 I/O 慢导致大量 D 状态进程、频繁的上下文切换和中断。

3. 常用工具与关键字段​

工具看什么关键字段
top / htop整体和进程级 CPU、内存us 用户态、sy 内核态、wa 等待 I/O、si 软中断、st 被虚拟化宿主占用;进程的 %CPU、RES、状态
vmstat 1运行队列、内存、交换、上下文切换r 等待 CPU 的进程数、b 阻塞的进程数、si/so 交换、cs 上下文切换、wa
free -h内存看 available 而不是 free;buff/cache 可回收
iostat -x 1每块磁盘的 I/Or_await/w_await 平均等待时间、aqu-sz 队列长度、%util 忙碌比例
pidstat -u/-d/-w 1按进程看 CPU、I/O、上下文切换定位到具体进程
iotop按进程看实时磁盘读写找出 I/O 最多的进程
perf top热点函数定位到函数,包括内核函数
dmesg内核日志OOM Killer、磁盘错误

iostat 按磁盘统计,用于判断哪块盘有压力;iotop 按进程统计,用于找出是谁在读写。%util 接近 100% 对单块机械盘意味着饱和,但 SSD 和 RAID 可以并行处理请求,%util 高不一定饱和,要结合 await 判断。

4. 三类场景的排查路径​

CPU 使用率高

  1. top 按 CPU 排序找到进程,看 us 和 sy 的比例。
  2. us 高:业务计算多。top -Hp <pid> 找到最忙的线程,用 perf top -p <pid> 或语言自带工具(Java 用 jstack,把线程 ID 转成十六进制后在线程栈中查找)定位代码。常见原因有死循环、正则回溯、序列化大对象、频繁 GC。
  3. sy 高:系统调用、上下文切换或中断过多。用 vmstat 看 cs,pidstat -w 找切换多的进程,strace -c -p <pid> 统计系统调用。常见原因有线程过多、锁竞争、小块读写。
  4. si 高:软中断,通常是网络包量大。

系统卡、内存和 CPU 都高

  1. free 看 available 是否很低,vmstat 的 si/so 是否持续不为零。发生交换时,进程访问内存要等磁盘,整体变慢。
  2. 按内存排序找到占用最多的进程,判断是正常增长(缓存)还是泄漏(持续上涨不回落)。
  3. dmesg | grep -i oom 检查是否有进程被 OOM Killer 杀掉。
  4. 内存紧张时 GC 也会更频繁,CPU 随之升高,要确认因果顺序。

CPU 不高但接口慢

  1. I/O:vmstat 的 wa 和 b 是否高,iostat 的 await 是否升高,iotop 找出读写多的进程(日志、备份、数据库)。
  2. 网络:到下游的延迟和丢包(ping、mtr),连接状态是否异常(ss -s),DNS 解析是否慢。
  3. 应用内部:线程池、连接池是否耗尽,是否在等锁;线程栈中大量线程处于等待状态说明在等资源。
  4. 下游依赖:数据库慢查询、缓存失效、第三方接口变慢。用链路追踪看耗时在哪一段,见日志、指标与追踪。

5 · 面试题卡片​

5.1 top 显示的 load average 三个数字是什么含义?怎样判断 CPU 处于高负载?负载高可能有哪些原因?​

出现公司:京东、百度、触宝、字节跳动

考察重点

  • 负载统计的是 R 和 D 状态的进程数,不是使用率。
  • 与核数比较的判断方法;区分 CPU 忙和 I/O 等待。

相关内容:load average、常用工具与关键字段。

参考回答

三个数是最近 1、5、15 分钟的平均负载,按指数加权计算。Linux 统计的是处于可运行状态(正在运行或等待 CPU)和不可中断睡眠状态(通常在等磁盘 I/O)的进程数,所以它表示排队的程度,不是 CPU 使用率。

判断时和核数比较:负载持续高于核数,说明有任务在排队;1 分钟值远高于 15 分钟值,说明负载正在上升。负载高之后还要区分原因:top 中 us、sy 高是 CPU 忙,可能是计算密集、线程过多竞争、频繁上下文切换;wa 高、vmstat 中 b 列大,是大量进程在等 I/O,CPU 使用率可能并不高。负载过高的后果是请求排队,响应时间变长,严重时健康检查超时、服务被摘除。

5.2 发现某台机器 CPU 使用率很高、系统很卡,你怎样排查?​

出现公司:虾皮、哔哩哔哩、持安科技

考察重点

  • 从机器到进程、线程、代码的定位链路。
  • 区分用户态与内核态;内存不足引起的交换与 OOM。

相关内容:三类场景的排查路径、Java CPU 飙高排查。

参考回答

先看监控确认开始时间,是否和发布、流量突增同时发生。登录机器后用 top 按 CPU 排序找到进程,看 us 和 sy 的比例。us 高是业务计算,用 top -Hp <pid> 找到最忙的线程,再用 perf top 或语言工具定位代码,Java 进程把线程 ID 转成十六进制后在 jstack 输出中找对应栈,常见原因是死循环、正则回溯、大对象序列化和频繁 GC。sy 高是系统调用或上下文切换多,用 vmstat 看 cs、pidstat -w 找切换多的进程,strace -c 统计系统调用。

如果内存也高,用 free 看 available,vmstat 看 si/so:发生交换时所有访问都会变慢;dmesg 检查 OOM Killer 记录;按内存排序找到进程,判断是缓存增长还是泄漏。止血可以先摘流量、扩容或重启,但要先保留线程栈、堆转储等现场。

5.3 一台 Linux 服务器 CPU 占用不高,但接口访问很慢,你会怎样排查?​

出现公司:共济科技、美团、字节跳动、杭州观远数据

考察重点

  • CPU 不高说明在等待:I/O、网络、锁、池耗尽、下游。
  • iostat 与 iotop 的分工;按层次排除。

相关内容:三类场景的排查路径、常用工具与关键字段。

参考回答

CPU 不高而响应慢,说明请求大部分时间在等待,要找出在等什么。先看机器:vmstat 的 wa 和 b 列是否高,iostat -x 看哪块盘的 await 和队列长度升高,再用 iotop 或 pidstat -d 找出读写最多的进程,例如日志刷盘、备份任务;free 确认没有发生交换。

然后看网络:到下游的延迟和丢包,ss -s 看连接数和异常状态,DNS 解析是否变慢。再看应用内部:线程池或连接池是否耗尽,线程栈中是否有大量线程在等锁或等连接。最后看下游依赖:数据库慢查询、缓存命中率下降、第三方接口变慢。用链路追踪可以直接看到耗时集中在哪一段,比逐台机器排查更快。

6. 参考资料​