你好,我是风一样的树懒,一个工作十多年的后端开发,曾就职京东、阿里等多家互联网头部企业。
文章可能会比较长,主要解析的非常详解,或涉及一些底层知识,供面试高阶难度用。可以根据自己实际理解情况合理取舍阅读
当遇到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 30perf script > out.perfFlameGraph/stackcollapse-perf.pl out.perf | FlameGraph/flamegraph.pl > flame.svg
# 生成线程快照jstack <PID> > thread_dump.txt# 结合top定位线程top -H -p <PID> # 显示线程级CPUprintf "%x\n" <TID> # 将线程ID转为十六进制grep 'nid=0x<hex>' thread_dump.txt # 查找对应线程
# 安装并附加到Java进程curl -O https://arthas.aliyun.com/arthas-boot.jarjava -jar arthas-boot.jar# 监控热点方法dashboard # 实时监控面板thread -n 3 # 最忙线程Top3profiler 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 QPSif (limiter.tryAcquire()) {processRequest();}
graph TDA[CPU飙升告警] --> B{定位问题进程}B -->|top/pidstat| C[确定目标PID]C --> D{是否Java进程?}D -->|是| E[jstack/Arthas分析]D -->|否| F[perf/strace分析]E --> G[定位热点线程/方法]F --> GG --> H{问题类型}H --> I[死循环/GC/锁竞争...]I --> J[具体优化方案]
通过以上步骤,90%的CPU过高问题都能快速定位。建议将关键命令封装为排查脚本,例如:
#!/bin/bashecho "===== 系统负载 ====="uptimeecho "\n===== 进程Top5 ====="ps -eo pid,ppid,cmd,%cpu,%mem --sort=-%cpu | head -6echo "\n===== 网络连接 ====="ss -s
今天的内容就分享到这儿,喜欢的朋友可以关注,点赞。有什么不足的地方欢迎留言指出,您的关注是我前进的动力!