Linux 服务器 CPU 占用过高排查流程

一、问题现象

  • 系统响应变慢或无响应
  • 监控告警显示 CPU 使用率持续高于 80%
  • 业务服务出现超时或失败

二、快速定位

2.1 查看整体 CPU 使用情况

1
2
3
4
5
6
7
8
# 实时查看 CPU 使用率
top -bn1 | head -20

# 查看 CPU 核心使用情况
mpstat -P ALL 1 5

# 查看系统负载
uptime

2.2 识别占用 CPU 的进程

1
2
3
4
5
6
7
8
# 按 CPU 使用率排序进程
ps aux --sort=-%cpu | head -20

# 查看进程树
pstree -p -a

# 持续监控前 10 个进程
pidstat -u 1 10

三、深入分析

3.1 用户态 vs 内核态

1
2
3
4
5
6
7
8
# 查看 CPU 时间分布
vmstat 1 10

# 输出解读:
# us: 用户空间 CPU 时间
# sy: 内核空间 CPU 时间
# id: 空闲时间
# wa: I/O 等待时间

判断标准:

  • us 高:应用程序问题
  • sy 高:系统调用频繁或驱动问题
  • wa 高:I/O 瓶颈

3.2 线程级分析

1
2
3
4
5
6
7
8
9
10
11
# 获取进程 PID
PID=$(pgrep -f your_app)

# 查看进程内线程 CPU 使用
top -H -p $PID

# 查看线程堆栈
for i in $(ps -T -p $PID | awk '{print $2}'); do
echo "=== Thread $i ==="
cat /proc/$PID/task/$i/stack
done

3.3 系统调用分析

1
2
3
4
5
# 追踪系统调用
strace -c -p $PID

# 统计系统调用频率
strace -c -p $PID 2>&1 | head -30

四、常见原因及解决方案

4.1 应用层问题

现象 可能原因 解决方案
单进程 CPU 100% 死循环/复杂计算 检查代码逻辑,优化算法
多进程 CPU 高 并发量过大 限流、扩容
Java 应用 CPU 高 GC 频繁 调整 JVM 参数,检查内存泄漏

4.2 系统层问题

1
2
3
4
5
6
7
8
# 检查是否有僵尸进程
ps aux | awk '$8=="Z"'

# 检查中断分布
cat /proc/interrupts

# 检查软中断
cat /proc/softirqs

4.3 Java 应用专项排查

1
2
3
4
5
6
7
8
9
10
11
# 获取 Java 进程 PID
jps -l

# 生成线程 dump
jstack $PID > thread_dump.txt

# 分析 CPU 热点
jstat -gcutil $PID 1000 10

# 使用 async-profiler
./profiler.sh -d 30 -f profile.html $PID

五、应急处理

5.1 临时降载

1
2
3
4
5
6
7
8
# 限制进程 CPU 使用率
cpulimit -p $PID -l 50

# 调整进程优先级
renice +10 -p $PID

# 暂停进程(谨慎使用)
kill -STOP $PID

5.2 服务重启

1
2
3
4
5
# 优雅重启
systemctl restart your_service

# 检查服务状态
systemctl status your_service

六、预防措施

  1. 监控告警: 配置 CPU 使用率告警阈值(建议 80%)
  2. 资源限制: 使用 cgroups 限制进程资源
  3. 容量规划: 定期评估业务增长,提前扩容
  4. 代码审查: 避免死循环和低效算法
  5. 压测演练: 定期进行压力测试发现瓶颈

七、排查流程图

1
2
3
4
5
6
7
CPU 告警 → top 定位进程 → ps 确认进程详情

用户态高?→ 是 → 应用层排查(代码/配置)
↓ 否
内核态高?→ 是 → 系统层排查(驱动/内核)
↓ 否
I/O 等待高?→ 是 → 磁盘/网络排查

文档生成时间:2026-03-03