• 真实案例:系统上线后Cpu使用率飙升如何排查?


    在这里插入图片描述

    其实这是个很常见的问题,也非常简单,那既然如此我为什么还要写呢?因为上次回答的时候我忘记将线程PID转换成16进制的命令了。

    所以我决定再重温一遍这个问题,当然贴心的我还给大家准备好了测试代码,大家可以实际操作一下,这样下次就不会忘记了。

    模拟一个高CPU场景

    public class HighCpuTest {
        public static void main(String[] args) {
            List cpus = new ArrayList<>();
    
            Thread highCpuThread = new Thread(()->{
                int i = 0;
                while (true){
                    HignCpu cpu = new HignCpu("Young、",i);
    
                    cpus.add(cpu);
                    System.out.println("high cpu size:" + cpus.size());
                    i ++;
                }
            });
            highCpuThread.setName("HignCpu");
            highCpuThread.start();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    在main方法中开启了一个线程,无限构建HighCpu对象。

    @Data
    @AllArgsConstructor
    public class HignCpu {
        private String name;
        private int age;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    准备好上面的代码,运行HighCpuTest,然后就可以开始一些列的操作来发现问题原因了。

    排查步骤

    第一步,使用 top 找到占用 CPU 最高的 Java 进程

    1. 监控cpu运行状,显示进程运行信息列表
    top -c
    
    2. 按CPU使用率排序,键入大写的P
    P
    
    • 1
    • 2
    • 3
    • 4
    • 5

    image-20220714101848399

    第二步,用 top -Hp 命令查看占用 CPU 最高的线程

    上一步用 top命令找到了那个 Java 进程。那一个进程中有那么多线程,不可能所有线程都一直占着 CPU 不放,这一步要做的就是揪出这个罪魁祸首,当然有可能不止一个。

    执行top -Hp pid命令,pid 就是前面的 Java 进程,我这个例子中就是 16738 ,完整命令为:

    top -Hp 16738,然后键入P (大写p),线程按照CPU使用率排序

    执行之后的效果如下

    image-20220714101911961

    查到占用CPU最高的那个线程 PID 为 16756

    第三步,查看堆栈信息,定位对应代码

    通过printf命令将其转化成16进制,之所以需要转化为16进制,是因为堆栈里,线程id是用16进制表示的。(我当时就是忘记这个命令了~)

    [root@review-dev ~]# printf "%x\n" 16756
    4174
    
    • 1
    • 2

    得到16进制的线程ID为4174。

    通过jstack命令查看堆栈信息

    jstack 16738 | grep '0x4174' -C10 --color
    
    • 1

    image-20220714101955578

    如上图,找到了耗CPU高的线程对应的线程名称“HighCpu”,以及看到了该线程正在执行代码的堆栈。

    最后,根据堆栈里的信息,定位到对应死循环代码,搞定。

    小结

    cpu使用率飙升后如何排查这个问题不仅面试中经常会问,而且在实际工作中也非常有用,大家最好根据上述步骤实际操作一下,这样才能记得住记得牢。

  • 相关阅读:
    【C语言刷题——Leetcode12道题】带你起飞,飞进垃圾堆
    boost 管理存储交易 作为存储提供商 boostd
    3D模型轻量化:无损精度和细节,轻量化处理3D模型的云原生工具
    运行python进行指定内容的文件名查找
    【Hack The Box】linux练习-- Mango
    HCIP—BGP邻居关系建立实验
    uniapp vue2、vue3 页面模板代码块设置
    Spring cloud Sentinel介绍和安装
    [SWPU2019]Web1
    JVM 全面深入
  • 原文地址:https://blog.csdn.net/agonie201218/article/details/125778897