首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Linux CPU 飙高的 10 大根因与排查思路!

Linux CPU 飙高的 10 大根因与排查思路!

作者头像
测试开发技术
发布2025-11-17 20:16:40
发布2025-11-17 20:16:40
110
举报
文章被收录于专栏:测试开发技术测试开发技术

Linux CPU 飙高的 10 大根因与排查思路:从监控告警到根本修复

适用场景与前置条件

  • • 应用场景:CPU 使用率超过 80%、某个进程莫名消耗大量 CPU、系统响应变慢。
  • • 前置条件:Linux RHEL 7+/Ubuntu 18.04+、root 或 sudo 权限、常见监控工具(top、perf、strace)。
  • • 性能基线:单核满载为 100%,多核情况下注意每个核心独立计算。

环境与版本矩阵

工具/命令

RHEL 7.x

RHEL 8.x

Ubuntu 18.04

用途

安装包

top

原生

原生

原生

实时进程监控

-

htop

yum

dnf

apt

增强 top

htop

perf

yum install perf

dnf

apt

CPU 火焰图

linux-tools

sar

sysstat

sysstat

sysstat

系统历史统计

sysstat

strace

yum

dnf

apt

系统调用追踪

strace

mpstat

sysstat

sysstat

sysstat

单核 CPU 监控

sysstat

iostat

sysstat

sysstat

sysstat

I/O 关联 CPU

sysstat


快速清单(Checklist)

  • • [ ] 第1步:实时监控整体 CPU 使用率与负载均衡。
  • • [ ] 第2步:定位消耗 CPU 最高的单个进程。
  • • [ ] 第3步:深入分析问题进程的线程与系统调用。
  • • [ ] 第4步:收集历史性能数据排查波动规律。
  • • [ ] 第5步:分析代码/系统调用热点(火焰图)。
  • • [ ] 第6步:判断根因(业务逻辑、死循环、I/O 阻塞、内核 bug)。
  • • [ ] 第7步:实施修复方案与回滚策略。
  • • [ ] 第8步:建立长期监控告警。

实施步骤

Step 1:快速诊断整体 CPU 状态

查看系统平均负载:

代码语言:javascript
复制
# 方法 1:使用 uptime
uptime

# 方法 2:查看 /proc/loadavg
cat /proc/loadavg

预期输出:

代码语言:javascript
复制
 10:45:32 up 10 days, 3:20, 2 users, load average: 2.45, 2.30, 2.15

参数解释:

  • load average: 2.45, 2.30, 2.15:分别为 1 分钟、5 分钟、15 分钟平均负载。
  • • 负载 = CPU 繁忙 + 等待队列。
  • 判断规则:负载 > CPU 核心数 说明系统饱和。

查看 CPU 核心数:

代码语言:javascript
复制
nproc
# 或
grep -c '^processor' /proc/cpuinfo

查看每个核心 CPU 使用率(实时):

代码语言:javascript
复制
# 方法 1:使用 mpstat(需 sysstat)
sudo mpstat -P ALL 1 5

# 方法 2:使用 top
top

mpstat 预期输出:

代码语言:javascript
复制
CPU    %usr  %nice  %sys  %iowait  %irq  %soft  %guest  %idle
 0    45.2   0.0   8.5    2.1     0.0   0.1    0.0    44.1
 1    78.9   0.0  15.3    2.1     0.0   0.1    0.0     3.6
 2    12.3   0.0   5.6    1.2     0.0   0.0    0.0    80.9

关键字段解释:

  • %usr:用户态 CPU(业务进程)。
  • %sys:系统态 CPU(内核调用)。
  • %iowait:等待 I/O 的 CPU(磁盘/网络 I/O)。
  • %idle:空闲 CPU。

Step 2:定位高 CPU 消耗进程

使用 top 找高 CPU 进程:

代码语言:javascript
复制
top

交互命令:

  • Shift + P:按 CPU 使用率排序(默认)。
  • Shift + M:按内存使用率排序。
  • d 1:刷新频率改为 1 秒。
  • q:退出。

预期输出示例:

代码语言:javascript
复制
  PID USER    PR NI    VIRT    RES  %CPU %MEM TIME+ COMMAND
 5678 www     20  0  512m  256m  95.2  5.6 45:23 java -jar app.jar
 1234 mysql   20  0  1.5g  800m  12.3 22.1 102:45 /usr/sbin/mysqld

使用 ps 查看特定进程 CPU:

代码语言:javascript
复制
# 查看所有进程按 CPU 排序(静态快照)
ps aux --sort=-%cpu | head -10

# 查看特定进程 CPU
ps -p 5678 -o pid,cmd,%cpu,%mem

# 查看进程所有线程的 CPU
ps -p 5678 -L -o pid,tid,cmd,%cpu

预期输出:

代码语言:javascript
复制
  PID CMD                  %CPU %MEM
 5678 java -jar app.jar   95.2  5.6

定位线程级热点(多线程应用):

代码语言:javascript
复制
# 查看进程的线程信息
ps -eLf | grep 5678

# 实时监控线程 CPU 使用
top -p 5678 -H

Step 3:深入分析问题进程的系统调用

使用 strace 追踪系统调用:

代码语言:javascript
复制
# 追踪特定进程的所有系统调用
sudo strace -p 5678 -e trace=all -c

# 统计系统调用耗时(找耗时操作)
sudo strace -p 5678 -c -S time

预期输出(strace -c):

代码语言:javascript
复制
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 45.20    2.451234      245      10000         0 futex
 32.10    1.743210      174       10010         0 poll
 15.30    0.831245       83       10020         0 read
  5.40    0.293215       29       10030         0 write

参数说明:

  • futex:线程间同步/互斥锁等待(高频表示锁竞争激烈)。
  • poll/epoll:I/O 多路复用等待。
  • • 高 %time 的调用需进一步优化。

使用 perf 获取 CPU 火焰图(精确定位热点):

代码语言:javascript
复制
# 安装 perf
sudo yum install -y perf  # RHEL/CentOS
# 或
sudo apt-get install -y linux-tools-generic  # Ubuntu

# 采样特定进程 30 秒
sudo perf record -p 5678 -F 99 sleep

# 生成报告
sudo perf report

# 导出为火焰图格式(需自行处理数据)
sudo perf script > out.perf

perf report 交互命令:

  • ↓↑:上下导航。
  • Enter:展开详情。
  • q:退出。

Step 4:收集历史 CPU 数据排查规律

使用 sar 查看历史 CPU 数据:

代码语言:javascript
复制
# 需先启用 sysstat(编辑 /etc/cron.d/sysstat 或系统服务)
sudo yum install -y sysstat

# 查看今天的 CPU 使用历史(10 分钟一个采样点)
sar -u -f /var/log/sa/sa$(date +%d)

# 查看过去 7 天的每小时平均 CPU
sar -u -f /var/log/sa/sa01 -b

# 按 1 分钟间隔采集数据(实时)
sar -u 1 10

预期输出:

代码语言:javascript
复制
10:30:00 AM  CPU     %user   %nice %system %iowait  %steal   %idle
10:31:00 AM  all     45.23    0.00   8.45    2.34    0.00   43.98
10:32:00 AM  all     48.12    0.01   9.21    1.87    0.00   40.79

识别 CPU 高峰规律:

代码语言:javascript
复制
# 查看过去 24 小时的 CPU 趋势
sar -u -f /var/log/sa/sa$(date +%d) | tail -20

Step 5:分析代码热点(火焰图)

生成 CPU 火焰图(Java 应用示例):

代码语言:javascript
复制
# Step 1:安装 flamegraph 工具
git clone https://github.com/brendangregg/FlameGraph.git
export PATH=$PATH:$(pwd)/FlameGraph

# Step 2:使用 perf 采样
sudo perf record -F 99 -p 5678 -g -- sleep

# Step 3:导出调用栈
sudo perf script > out.perf

# Step 4:生成火焰图
stackcollapse-perf.pl out.perf | flamegraph.pl > cpu_flame.svg

# Step 5:用浏览器查看 cpu_flame.svg

火焰图解读:

  • • 横向宽度:函数调用次数(越宽表示消耗 CPU 时间越多)。
  • • 纵向高度:调用栈深度。
  • • 点击区域可进行交互(放大、重置)。

Step 6:CPU 飙高的 10 大根因与判断标准

根因

症状表现

诊断命令

判断标准

快速修复

1. 业务代码 CPU 密集

CPU 持续高位,%usr 高

perf report

火焰图中业务函数占比 > 70%

优化算法/加缓存

2. 死循环/无限递归

单进程 CPU 100%,无 I/O 等待

strace -p PID -c

某个系统调用极高频

查代码、打日志

3. 锁竞争激烈

%sys 高,futex 系统调用多

strace -p PID -e futex

futex 高频且耗时

减少临界区、细粒度锁

4. 频繁上下文切换

CPU 高但不满载、进程数多

vmstat 1 | watch -n 1

cs(上下文切换)> 50000/s

限制线程数/使用 CPU 亲和性

5. 中断处理过多

%irq/%soft 高

cat /proc/interrupts

网卡/存储中断高

调整网卡/磁盘驱动参数

6. I/O 密集(隐性 CPU)

%iowait 高、等待 I/O 的进程多

iostat -x 1

wa > 20%

优化 I/O 模式/换 SSD

7. 内核内存回收

%sys 高、free 内存低

vmstat 1 | awk '{print $8}'

kswapd 进程 CPU 高

增加内存/优化应用内存

8. 网络收包处理

%irq/%soft 高、网络流量大

sar -n DEV 1 10

Rxpck/s > 100k

调整网卡中断配置/增加队列

9. 进程调度抖动

进程 CPU 波动大、缓存命中率低

perf stat -p PID -e cache-misses

cache miss > 30%

绑定 CPU/优化内存访问模式

10. 内核 bug/驱动问题

无明显业务高负载但 CPU 高

sudo dmesg | tail

内核 Warning/Error 日志

升级内核/驱动版本


Step 7:实施修复方案

方案 A:进程级优化(不重启应用):

代码语言:javascript
复制
# 1. 限制进程 CPU 使用(cgroup)
cgcreate -g cpu:/limited_app
cgset -r cpu.cfs_quota_us=80000 /limited_app  # 限制为 80% 一个 CPU
cgexec -g cpu:/limited_app /opt/app/start.sh

# 2. CPU 亲和性绑定(避免频繁迁移)
taskset -pc 0,1,2 5678  # 绑定进程 5678 到 CPU 0,1,2

# 3. 调整进程优先级
nice -n 10 /opt/app/start.sh  # 降低优先级
# 或
renice -n 10 -p 5678

方案 B:系统级调优:

代码语言:javascript
复制
# 1. 禁用 CPU 频率缩放(固定最高频率以提升性能)
sudo vi /etc/default/grub
# 添加启动参数:intel_pstate=disable cpufreq=performance
sudo grub2-mkconfig -o /boot/grub2/grub.cfg
sudo reboot

# 2. 调整进程调度器
echo deadline > /sys/block/sda/queue/scheduler  # 磁盘 I/O 调度
echo nohz_full=2-3 >> /proc/cmdline  # 使用内核参数

# 3. 关闭不必要的中断
sudo ethtool -C eth0 rx-usecs 500  # 调整网卡中断合并间隔

方案 C:应用代码优化(示例 - Python):

代码语言:javascript
复制
# 问题:频繁的全局 GIL 锁竞争
# 解决方案 1:使用多进程而非多线程
from multiprocessing import Process

defworker(data):
# CPU 密集操作
pass

if __name__ == '__main__':
    processes = [Process(target=worker, args=(chunk,))
for chunk in data_chunks]
for p in processes:
        p.start()

# 解决方案 2:使用 C 扩展或 NumPy(绕过 GIL)
import numpy as np
# NumPy 操作不受 GIL 限制
result = np.dot(matrix1, matrix2)  # 并行计算

Step 8:建立监控告警

Prometheus 监控配置:

代码语言:javascript
复制
# prometheus.yml
scrape_configs:
-job_name:'node'
static_configs:
-targets: ['localhost:9100']

# alert_rules.yml
groups:
-name:cpu_alerts
rules:
-alert:CPUHigh
expr:(100-avgby(instance)(irate(node_cpu_seconds_total{mode="idle"}[5m]))*)>
for:5m
annotations:
summary:"High CPU on {{ $labels.instance }}"

-alert:LoadAverage
expr:node_load1>(countby(instance)(node_cpu_seconds_total{mode="idle"})*1.5)
for:5m
annotations:
summary:"High load average on {{ $labels.instance }}"

Grafana 仪表板指标:

  • • CPU 使用率趋势(过去 24 小时)。
  • • 单核 CPU 分布。
  • • 进程 CPU TOP 10。
  • • 负载均衡与调度延迟。

性能优化基准

CPU 优化目标:

  • • 业务 CPU:降低 20-50%(通过算法/缓存优化)。
  • • 系统 CPU:< 10%(正常运维开销)。
  • • I/O 等待:< 5%(高效磁盘/网络配置)。

最佳实践

  1. 1. 分层排查:先看全局负载,再定位进程,最后深入代码。
  2. 2. 采样法排查:不要盲目优化,用 perf/火焰图找真正的热点。
  3. 3. 隔离问题进程:使用 cgroup 限制其他进程 CPU,确保主要服务可用。
  4. 4. 定期审计:每周查看 sar 历史数据,发现异常趋势。
  5. 5. 负载均衡:多进程/多线程充分利用多核,但注意锁竞争。
  6. 6. 版本控制:记录每次优化的内核/驱动/应用版本,便于回滚。
  7. 7. 测试验证:压测新优化方案,确保无副作用。

附录:常用命令速查

代码语言:javascript
复制
# 实时监控
top / htop / watch 'mpstat -P ALL 1 1'

# 历史数据
sar -u -f /var/log/sa/saXX

# 进程深度分析
ps aux / ps -eLf / top -H -p PID / ps -p PID -o tid,%cpu,cmd

# 系统调用追踪
strace -p PID -c -S time / sudo perf record -p PID -g

# 火焰图
sudo perf script | stackcollapse-perf.pl | flamegraph.pl

# 中断/负载
cat /proc/interrupts / vmstat 1 / uptime

# 调度统计
cat /proc/sched_debug / pidstat -w 1

总结:CPU 飙高排查需要分层思维——先看系统全局(负载、核心分布),再定位进程(top/ps),最后深入代码(perf/火焰图)。掌握 10 大根因的判断标准与快速诊断命令,就能在几分钟内找到病根。关键是搭建长期的 sar/Prometheus 监控,提前发现异常趋势,防患于未然。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-10-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 测试开发技术 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Linux CPU 飙高的 10 大根因与排查思路:从监控告警到根本修复
    • 适用场景与前置条件
    • 环境与版本矩阵
    • 快速清单(Checklist)
    • 实施步骤
      • Step 1:快速诊断整体 CPU 状态
      • Step 2:定位高 CPU 消耗进程
      • Step 3:深入分析问题进程的系统调用
      • Step 4:收集历史 CPU 数据排查规律
      • Step 5:分析代码热点(火焰图)
      • Step 6:CPU 飙高的 10 大根因与判断标准
      • Step 7:实施修复方案
      • Step 8:建立监控告警
    • 性能优化基准
    • 最佳实践
    • 附录:常用命令速查
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档