关注「Raymond运维」公众号,并设为「星标」,也可以扫描底部二维码加入群聊,第一时间获取最新内容,不再错过精彩内容。
Linux CPU 飙高的 10 大根因与排查思路:从监控告警到根本修复
引流标题(SEO)
Linux CPU 飙高诊断指南:10 大根因速查表、分钟内定位问题进程、企业级排查工具集
适用场景与前置条件
- • 应用场景:CPU 使用率超过 80%、某个进程莫名消耗大量 CPU、系统响应变慢。
- • 前置条件:Linux RHEL 7+/Ubuntu 18.04+、root 或 sudo 权限、常见监控工具(top、perf、strace)。
- • 性能基线:单核满载为 100%,多核情况下注意每个核心独立计算。
环境与版本矩阵
快速清单(Checklist)
- • [ ] 第1步:实时监控整体 CPU 使用率与负载均衡。
- • [ ] 第2步:定位消耗 CPU 最高的单个进程。
- • [ ] 第3步:深入分析问题进程的线程与系统调用。
- • [ ] 第4步:收集历史性能数据排查波动规律。
- • [ ] 第5步:分析代码/系统调用热点(火焰图)。
- • [ ] 第6步:判断根因(业务逻辑、死循环、I/O 阻塞、内核 bug)。
实施步骤
Step 1:快速诊断整体 CPU 状态
查看系统平均负载:
# 方法 1:使用 uptimeuptime# 方法 2:查看 /proc/loadavgcat /proc/loadavg
预期输出:
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 核心数:
nproc# 或grep -c '^processor' /proc/cpuinfo
查看每个核心 CPU 使用率(实时):
# 方法 1:使用 mpstat(需 sysstat)sudo mpstat -P ALL 1 5# 方法 2:使用 toptop
mpstat 预期输出:
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
关键字段解释:
- •
%iowait:等待 I/O 的 CPU(磁盘/网络 I/O)。
Step 2:定位高 CPU 消耗进程
使用 top 找高 CPU 进程:
top
交互命令:
- •
Shift + P:按 CPU 使用率排序(默认)。
预期输出示例:
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:
# 查看所有进程按 CPU 排序(静态快照)ps aux --sort=-%cpu | head -10# 查看特定进程 CPUps -p 5678 -o pid,cmd,%cpu,%mem# 查看进程所有线程的 CPUps -p 5678 -L -o pid,tid,cmd,%cpu
预期输出:
PID CMD %CPU %MEM 5678 java -jar app.jar 95.2 5.6
定位线程级热点(多线程应用):
# 查看进程的线程信息ps -eLf | grep 5678# 实时监控线程 CPU 使用top -p 5678 -H
Step 3:深入分析问题进程的系统调用
使用 strace 追踪系统调用:
# 追踪特定进程的所有系统调用sudo strace -p 5678 -e trace=all -c# 统计系统调用耗时(找耗时操作)sudo strace -p 5678 -c -S time
预期输出(strace -c):
% 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:线程间同步/互斥锁等待(高频表示锁竞争激烈)。
使用 perf 获取 CPU 火焰图(精确定位热点):
# 安装 perfsudo yum install -y perf # RHEL/CentOS# 或sudo apt-get install -y linux-tools-generic # Ubuntu# 采样特定进程 30 秒sudo perf record -p 5678 -F 99 sleep 30# 生成报告sudo perf report# 导出为火焰图格式(需自行处理数据)sudo perf script > out.perf
perf report 交互命令:
Step 4:收集历史 CPU 数据排查规律
使用 sar 查看历史 CPU 数据:
# 需先启用 sysstat(编辑 /etc/cron.d/sysstat 或系统服务)sudo yum install -y sysstat# 查看今天的 CPU 使用历史(10 分钟一个采样点)sar -u -f /var/log/sa/sa$(date +%d)# 查看过去 7 天的每小时平均 CPUsar -u -f /var/log/sa/sa01 -b# 按 1 分钟间隔采集数据(实时)sar -u 1 10
预期输出:
10:30:00 AM CPU %user %nice %system %iowait %steal %idle10:31:00 AM all 45.23 0.00 8.45 2.34 0.00 43.9810:32:00 AM all 48.12 0.01 9.21 1.87 0.00 40.79
识别 CPU 高峰规律:
# 查看过去 24 小时的 CPU 趋势sar -u -f /var/log/sa/sa$(date +%d) | tail -20
Step 5:分析代码热点(火焰图)
生成 CPU 火焰图(Java 应用示例):
# Step 1:安装 flamegraph 工具git clone https://github.com/brendangregg/FlameGraph.gitexport PATH=$PATH:$(pwd)/FlameGraph# Step 2:使用 perf 采样sudo perf record -F 99 -p 5678 -g -- sleep 30# 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 密集 | | perf report | | |
| 2. 死循环/无限递归 | | strace -p PID -c | | |
| 3. 锁竞争激烈 | | strace -p PID -e futex | | |
| 4. 频繁上下文切换 | | vmstat 1 | watch -n 1 | | |
| 5. 中断处理过多 | | cat /proc/interrupts | | |
| 6. I/O 密集(隐性 CPU) | | iostat -x 1 | | |
| 7. 内核内存回收 | | vmstat 1 | awk '{print $8}' | | |
| 8. 网络收包处理 | | sar -n DEV 1 10 | | |
| 9. 进程调度抖动 | | perf stat -p PID -e cache-misses | | |
| 10. 内核 bug/驱动问题 | | sudo dmesg | tail | | |
Step 7:实施修复方案
方案 A:进程级优化(不重启应用):
# 1. 限制进程 CPU 使用(cgroup)cgcreate -g cpu:/limited_appcgset -r cpu.cfs_quota_us=80000 /limited_app # 限制为 80% 一个 CPUcgexec -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:系统级调优:
# 1. 禁用 CPU 频率缩放(固定最高频率以提升性能)sudo vi /etc/default/grub# 添加启动参数:intel_pstate=disable cpufreq=performancesudo grub2-mkconfig -o /boot/grub2/grub.cfgsudo 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):
# 问题:频繁的全局 GIL 锁竞争# 解决方案 1:使用多进程而非多线程from multiprocessing import Processdefworker(data):# CPU 密集操作passif __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 监控配置:
# prometheus.ymlscrape_configs:-job_name:'node'static_configs:-targets: ['localhost:9100']# alert_rules.ymlgroups:-name:cpu_alertsrules:-alert:CPUHighexpr:(100-avgby(instance)(irate(node_cpu_seconds_total{mode="idle"}[5m]))*100)>80for:5mannotations:summary:"High CPU on {{ $labels.instance }}"-alert:LoadAverageexpr:node_load1>(countby(instance)(node_cpu_seconds_total{mode="idle"})*1.5)for:5mannotations:summary:"High load average on {{ $labels.instance }}"
Grafana 仪表板指标:
性能优化基准
CPU 优化目标:
- • 业务 CPU:降低 20-50%(通过算法/缓存优化)。
- • I/O 等待:< 5%(高效磁盘/网络配置)。
最佳实践
- 1. 分层排查:先看全局负载,再定位进程,最后深入代码。
- 2. 采样法排查:不要盲目优化,用 perf/火焰图找真正的热点。
- 3. 隔离问题进程:使用 cgroup 限制其他进程 CPU,确保主要服务可用。
- 4. 定期审计:每周查看 sar 历史数据,发现异常趋势。
- 5. 负载均衡:多进程/多线程充分利用多核,但注意锁竞争。
- 6. 版本控制:记录每次优化的内核/驱动/应用版本,便于回滚。
附录:常用命令速查
# 实时监控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 监控,提前发现异常趋势,防患于未然。
为了方便大家更好的交流运维等相关技术问题,创建了微信交流群,需要加群的小伙伴们可以扫一扫下面的二维码加我为好友拉您进群(备注:加群)。

| 代码仓库 | 网址 |
| Github | https://github.com/raymond999999 |
| Gitee | https://gitee.com/raymond9 |
| 博客 | 网址 |
| https://blog.csdn.net/qq_25599925 |
| 稀土掘金 | https://juejin.cn/user/4262187909781751 |
| 知识星球 | https://wx.zsxq.com/group/15555885545422 |
| 阿里云社区 | https://developer.aliyun.com/profile/snzh3xpxaf6sg |
| 腾讯云社区 | https://cloud.tencent.com/developer/user/11823619 |
| 华为云社区 | https://developer.huaweicloud.com/usercenter/mycommunity/dynamics |
访问博客网站,查看更多优质原创内容。