你好,我是风一样的树懒,一个工作十多年的后端开发,曾就职京东、阿里等多家互联网头部企业。
文章可能会比较长,主要解析的非常详解,或涉及一些底层知识,供面试高阶难度用。可以根据自己实际理解情况合理取舍阅读
当遇到CPU使用率过高的问题时,可以按照以下 阶梯式排查流程 逐步定位问题根源:
# 按CPU使用率排序(Linux)
top -c -o %CPU # 交互式查看
ps -eo pid,ppid,cmd,%cpu,%mem --sort=-%cpu | head # 静态快照
docker stats # Docker容器资源统计
kubectl top pods # Kubernetes Pod资源监控
# 按进程ID监控(每2秒刷新)
pidstat -p <PID> 2 -u # CPU使用详情
pidstat -t -p <PID> 2 # 线程级分解
# 生成CPU火焰图(需安装perf)
perf record -F 99 -p <PID> -g -- sleep 30
perf script > out.perf
FlameGraph/stackcollapse-perf.pl out.perf | FlameGraph/flamegraph.pl > flame.svg
# 生成线程快照
jstack <PID> > thread_dump.txt
# 结合top定位线程
top -H -p <PID> # 显示线程级CPU
printf "%x\n" <TID> # 将线程ID转为十六进制
grep 'nid=0x<hex>' thread_dump.txt # 查找对应线程
# 安装并附加到Java进程
curl -O https://arthas.aliyun.com/arthas-boot.jar
java -jar arthas-boot.jar
# 监控热点方法
dashboard # 实时监控面板
thread -n 3 # 最忙线程Top3
profiler start # 开始采样
profiler stop # 生成火焰图
vmstat 2 5 # 查看cs字段(上下文切换)
pidstat -w -p <PID> 2 # 特定进程上下文切换
cat /proc/interrupts # 硬件中断分布
cat /proc/softirqs # 软中断统计
sar -q 1 3 # 队列长度监控
问题模式 | 解决方案 | 检测方法 |
死循环 | 添加循环退出条件/Thread.sleep | 线程堆栈显示RUNNABLE状态循环 |
频繁GC | 调整JVM参数/优化对象创建 | jstat -gcutil |
锁竞争激烈 | 减小锁粒度/改用CAS操作 | jstack显示大量BLOCKED线程 |
正则表达式回溯 | 优化正则表达式 | CPU消耗集中在Pattern匹配 |
算法复杂度高 | 优化算法/引入缓存 | 火焰图显示核心算法函数 |
复制
renice 19 <PID> # 降低进程优先级
kill -STOP <PID> # 暂停进程(慎用)
// 使用Guava RateLimiter限流
RateLimiter limiter = RateLimiter.create(100); // 100 QPS
if (limiter.tryAcquire()) {
processRequest();
}
graph TD
A[CPU飙升告警] --> B{定位问题进程}
B -->|top/pidstat| C[确定目标PID]
C --> D{是否Java进程?}
D -->|是| E[jstack/Arthas分析]
D -->|否| F[perf/strace分析]
E --> G[定位热点线程/方法]
F --> G
G --> H{问题类型}
H --> I[死循环/GC/锁竞争...]
I --> J[具体优化方案]
通过以上步骤,90%的CPU过高问题都能快速定位。建议将关键命令封装为排查脚本,例如:
#!/bin/bash
echo "===== 系统负载 ====="
uptime
echo "\n===== 进程Top5 ====="
ps -eo pid,ppid,cmd,%cpu,%mem --sort=-%cpu | head -6
echo "\n===== 网络连接 ====="
ss -s
今天的内容就分享到这儿,喜欢的朋友可以关注,点赞。有什么不足的地方欢迎留言指出,您的关注是我前进的动力!