日本一意孤行?国际原子能机构认为福岛处理水排海计划符合国际安全标准

普里戈津之死!我的三点评论!

从人类历史,看人类未来

目录一览!马工程重点教材《习近平新时代中国特色社会主义思想概论》

从福岛核废水说起:我们是在谈科学还是讲立场

生成图片,分享到微信朋友圈

自由微信安卓APP发布,立即下载! | 提交文章网址
查看原文

重点问题!CPU利用率过高排查思路|原创

阿笠在健身 后端开发技术 2023-02-20

本文讲解了重点面试问题CPU利用率高如何排查和解决。

点击上方“后端开发技术”,选择“设为星标” ,优质资源及时送达

CPU利用率高怎么办?如何排查和解决

这是一个常见的面试问题,也是线上常遇到的问题之一。遇到线上服务器异常告警,我们的首要目标不是定位问题,而是尽快恢复服务可用,消除影响。

往往这种时候不能一次性定位并解决问题,如果服务不可用我们要优先让服务可用,如果有数据异常我们要优先修复数据,也可能对此有应急方案,优先让服务恢复正常是重中之重。然后我们可以尽量去保留现场信息,比如内存dump、mysql log、gc log等,事后再去定位、解决问题和复盘。

问题场景

通常会收到监控系统告警,相关服务器负载异常,cpu使用率过高

原因:可能是业务代码死循环、GC频繁、线程阻塞等

模拟问题

为了在测试环境模拟这种情况,这里以一个简单的死循环为例子,具体操作如下:

1.可以直接在服务器创建文件

touch Test.java

2.然后编辑Test.java文件

vi Test.java

输入如下代码,然后wq保存。

public class Test {
    public static void main(String[] args) {
        Thread thread = new Thread(() -> {
            int a = 3;
            while (true) {
                if (a == 3) {
                    a = a / 2;
                } else {
                    a = 3;
                }
            }
        });
        thread.start();
    }
}

3.命令行编译生成 Test.class文件。

javac Test.java

4.命令行执行测试文件。

java Test

问题排查

1.执行top 命令查看占用cpu最多的Java进程。

top

2.根据pid找到对应cpu占用最多的Java线程。

top -Hp 4861

3.将10进制线程id转换为16进制。

[root@node1 ~]# printf '%x\n' 4861
12fd

4.通过jstack 命令找到对应问题现场堆栈信息。

root@node1 ~]# jstack 4851|grep 12fd -C 10
2022-06-07 19:01:25
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.281-b09 mixed mode):

"Attach Listener" #10 daemon prio=9 os_prio=0 tid=0x00007fe7c8001000 nid=0x14fa waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"DestroyJavaVM" #9 prio=5 os_prio=0 tid=0x00007fe7f0009800 nid=0x149a waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Thread-0" #8 prio=5 os_prio=0 tid=0x00007fe7f00f6000 nid=0x12fd runnable [0x00007fe7f411a000]
   java.lang.Thread.State: RUNNABLE
 at Test.lambda$main$0(Test.java:7)
 at Test$$Lambda$1/471910020.run(Unknown Source)
 at java.lang.Thread.run(Thread.java:748)

"Service Thread" #7 daemon prio=9 os_prio=0 tid=0x00007fe7f00b6000 nid=0x14a1 runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C1 CompilerThread1" #6 daemon prio=9 os_prio=0 tid=0x00007fe7f00b3800 nid=0x14a0 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

可以看到,问题线程处于runnable状态,可以对应定位到问题代码Test.java:7,发现死循环。

解决问题

对于CPU占用率飙高的场景,刚才列举的测试代码只是一种情况,还有如下可能。

1.业务线程出现大量阻塞,比如synchronized锁,可以检索状态为BLOCKED的线程找到堆栈信息,然后分析。

2.网络IO或者磁盘IO阻塞导致的,排查方法和上面一样。

3.GC线程频繁导致,线程的标识为GC task thread,对于这种情况可能是年轻代设置不合理、大对象分配过多,old区存活对象过多,具体问题具体分析。

如果对你有帮助,欢迎点赞、评论分享,感谢阅读

update在MySQL中是怎样执行的,一张图牢记|原创

2022-11-19

讲真,这篇最全HashMap你不能错过!|原创

2022-11-17

MySQL主从数据不一致,怎么办?

2022-11-11

文章有问题?点此查看未经处理的缓存