工具/命令 | 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 |
查看系统平均负载:
# 方法 1:使用 uptime
uptime
# 方法 2:查看 /proc/loadavg
cat /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 核心数:
nproc
# 或
grep -c '^processor' /proc/cpuinfo
查看每个核心 CPU 使用率(实时):
# 方法 1:使用 mpstat(需 sysstat)
sudo mpstat -P ALL 1 5
# 方法 2:使用 top
top
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
关键字段解释:
%usr:用户态 CPU(业务进程)。%sys:系统态 CPU(内核调用)。%iowait:等待 I/O 的 CPU(磁盘/网络 I/O)。%idle:空闲 CPU。使用 top 找高 CPU 进程:
top
交互命令:
Shift + P:按 CPU 使用率排序(默认)。Shift + M:按内存使用率排序。d 1:刷新频率改为 1 秒。q:退出。预期输出示例:
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
# 查看特定进程 CPU
ps -p 5678 -o pid,cmd,%cpu,%mem
# 查看进程所有线程的 CPU
ps -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
使用 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:线程间同步/互斥锁等待(高频表示锁竞争激烈)。poll/epoll:I/O 多路复用等待。%time 的调用需进一步优化。使用 perf 获取 CPU 火焰图(精确定位热点):
# 安装 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:退出。使用 sar 查看历史 CPU 数据:
# 需先启用 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
预期输出:
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 高峰规律:
# 查看过去 24 小时的 CPU 趋势
sar -u -f /var/log/sa/sa$(date +%d) | tail -20
生成 CPU 火焰图(Java 应用示例):
# 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
火焰图解读:
根因 | 症状表现 | 诊断命令 | 判断标准 | 快速修复 |
|---|---|---|---|---|
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 日志 | 升级内核/驱动版本 |
方案 A:进程级优化(不重启应用):
# 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:系统级调优:
# 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):
# 问题:频繁的全局 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) # 并行计算
Prometheus 监控配置:
# 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 优化目标:
# 实时监控
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 监控,提前发现异常趋势,防患于未然。