线上问题排查之【CPU飙高100%】

目录

案例

发现问题

排查问题

步骤一

步骤二

步骤三


案例

import java.util.concurrent.TimeUnit;

/**
 * 简单写一个CPU飙高的案例
 */
public class CpuLoadUp {
    // 这里定义了一个标识
    private volatile static int flag = 0;

    public static void main(String[] args) {
        // 执行线程A的处理逻辑
        threadAProcess();

        // 执行线程B的处理逻辑
        threadBProcess();
    }

    public static void threadAProcess() {
        // 这里只是作为案例演示,实际上这里使用的是线程池
        new Thread(() -> {
            try {
                // 这里模拟业务逻辑需要处理很久
                TimeUnit.MINUTES.sleep(10);

                // 业务处理完之后更改标识flag为1
                flag = 1;
            } catch (InterruptedException e) {
                // 业务逻辑处理失败
            }
        }, "thread-A").start();
    }

    public static void threadBProcess() {
        // 这里只是案例演示,实际上这里使用的是线程池
        new Thread(() -> {
            // thread-A中的业务逻辑执行太久使得这里一直循环
            for (; ; ) {
                // 执行某业务逻辑

                // 直到flag为1时,执行结束,跳出循环
                if (flag == 1) {
                    break;
                }
            }
        }, "thread-B").start();
    }
}

发现问题

  • 使用【top】命令查看到有一个java进程CPU飙到100%,进程号为2567
  • 使用【jps】命令查看到正在运行的java程序
# top指令查看系统后台的进程状态
top

线上问题排查之【CPU飙高100%】_第1张图片

# jps指令查看正在运行的Java进程
jps

线上问题排查之【CPU飙高100%】_第2张图片

排查问题

步骤一

使用【top -Hp <进程ID>】查看进程中占用率最高的线程,占用率达到99.9%的线程PID为2578

top -Hp 2567

线上问题排查之【CPU飙高100%】_第3张图片

步骤二

将线程的PID转换为十六进制,结果是a12

public class MainTest {
    public static void main(String[] args) {
        // 查看2578的十六进制数,结果为a12
        System.out.println(Integer.toHexString(2578));
    }
}

步骤三

使用【jstack】命令查看线程堆栈信息,用十六进制线程ID搜索

# [-A 10]代表查看后10行信息
jstack 2567 | grep -A 10 'a12'

线上问题排查之【CPU飙高100%】_第4张图片

线上问题排查之【CPU飙高100%】_第5张图片

你可能感兴趣的:(线上问题排查,java)