线上CPU飙高如何排查?

线上CPU飙高如何排查?

一、详细排查步骤

1. 第一步:查看系统整体 CPU 使用情况

执行 top 命令,重点关注 %Cpu(s) 行:

  • us(用户态 CPU 占比):持续高于 80% → 用户进程消耗 CPU 多

  • sy(内核态 CPU 占比):持续高于 80% → 内核操作消耗 CPU 多

  • 只要两者其一持续超 80%,说明系统 CPU 压力大,需要进一步排查。

2. 第二步:定位高 CPU 的 Java 进程

top 命令界面中:

  • 按下 P 键(大写):按 CPU 使用率从高到低排序进程

  • 找到名称为 java 的进程,记下其 PID(进程 ID)。

3. 第三步:定位高 CPU 线程并抓取堆栈

这是排查的核心步骤,分 3 个子步骤:

# 1. 查看指定Java进程下的所有线程CPU占用(替换<PID>为实际进程ID)
top -H -p <PID>

# 2. 把高消耗线程的TID(线程ID)转为16进制(替换<TID>为实际线程ID)
printf "%x\n" <TID>

# 3. 抓取该线程的堆栈信息(替换<PID>和<hex_TID>)
jstack <PID> | grep -A 50 <hex_TID>
  • 堆栈结果中重点关注 RUNNABLE 状态的线程:这类线程是 CPU 消耗的主要来源,常见问题场景如下:

二、常见 CPU 飙高场景

问题类型

典型表现

正则表达式灾难性回溯

(.+)+ 等贪婪匹配的正则,匹配长字符串时 CPU 拉满

频繁序列化大对象

日志中输出大对象 JSON(Jackson/Gson 序列化)

线程池积压

外部依赖超时,大量线程 RUNNABLE 等待网络返回

四、补充说明

  • 线上应急排查:优先使用 top + jstack 组合,这是最稳定、最直接的方式。

  • 主动监控:代码中可通过 ThreadMXBean 监控线程 CPU 使用,但适合非应急场景。

  • 容器环境:需进入宿主机操作,或用 kubectl exec <容器名> -it -- /bin/bash 进入容器后执行命令。

总结

  1. CPU 飙高排查核心逻辑:系统→进程→线程 / 堆栈 三步递进,核心是定位高 CPU 线程并抓取堆栈。

  2. 关键命令:top(看系统 / 进程 / 线程)、printf(TID 转 16 进制)、jstack(抓堆栈)。

  3. 高频问题:正则回溯、大对象序列化、线程池积压是 Java 进程 CPU 飙高的最常见原因。

RabbitMQ 消息重复消费问题处理方案(消息幂等性) 2026-03-18
SpringBoot 是如何实现自动配置的? 2026-03-21

评论区