加入收藏 | 设为首页 | 会员中心 | 我要投稿 济南站长网 (https://www.0531zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 运营中心 > 网站设计 > 教程 > 正文

一次性搞清楚线上CPU100%,频繁FullGC排查套路

发布时间:2019-06-25 09:44:08 所属栏目:教程 来源:爱宝贝丶
导读:副标题#e# 处理过线上问题的同学基本上都会遇到系统突然运行缓慢,CPU 100%,以及 Full GC 次数过多的问题。 当然,这些问题最终导致的直观现象就是系统运行缓慢,并且有大量的报警。 本文主要针对系统运行缓慢这一问题,提供该问题的排查思路,从而定位出
副标题[/!--empirenews.page--]

处理过线上问题的同学基本上都会遇到系统突然运行缓慢,CPU 100%,以及 Full GC 次数过多的问题。

一次性搞清楚线上CPU100%,频繁FullGC排查套路

当然,这些问题最终导致的直观现象就是系统运行缓慢,并且有大量的报警。

本文主要针对系统运行缓慢这一问题,提供该问题的排查思路,从而定位出问题的代码点,进而提供解决该问题的思路。

对于线上系统突然产生的运行缓慢问题,如果该问题导致线上系统不可用,那么首先需要做的就是,导出 jstack 和内存信息,然后重启系统,尽快保证系统的可用性。

这种情况可能的原因主要有两种:

  • 代码中某个位置读取数据量较大,导致系统内存耗尽,从而导致 Full GC 次数过多,系统缓慢。
  • 代码中有比较耗 CPU 的操作,导致 CPU 过高,系统运行缓慢。

相对来说,这是出现频率最高的两种线上问题,而且它们会直接导致系统不可用。

另外有几种情况也会导致某个功能运行缓慢,但是不至于导致系统不可用:

  • 代码某个位置有阻塞性的操作,导致该功能调用整体比较耗时,但出现是比较随机的。
  • 某个线程由于某种原因而进入 WAITING 状态,此时该功能整体不可用,但是无法复现。
  • 由于锁使用不当,导致多个线程进入死锁状态,从而导致系统整体比较缓慢。

对于这三种情况,通过查看 CPU 和系统内存情况是无法查看出具体问题的,因为它们相对来说都是具有一定阻塞性操作,CPU 和系统内存使用情况都不高,但是功能却很慢。

下面我们就通过查看系统日志来一步一步甄别上述几种问题。

Full GC 次数过多

相对来说,这种情况是最容易出现的,尤其是新功能上线时。

对于 Full GC 较多的情况,其主要有如下两个特征:

  • 线上多个线程的 CPU 都超过了 100%,通过 jstack 命令可以看到这些线程主要是垃圾回收线程。
  • 通过 jstat 命令监控 GC 情况,可以看到 Full GC 次数非常多,并且次数在不断增加。

首先我们可以使用 top 命令查看系统 CPU 的占用情况,如下是系统 CPU 较高的一个示例:

  1. top - 08:31:10 up 30 min,  0 users,  load average: 0.73, 0.58, 0.34 
  2. KiB Mem:   2046460 total,  1923864 used,   122596 free,    14388 buffers 
  3. KiB Swap:  1048572 total,        0 used,  1048572 free.  1192352 cached Mem 
  4.  
  5.   PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND 
  6.     9 root      20   0 2557160 288976  15812 S  98.0 14.1   0:42.60 java 

可以看到,有一个 Java 程序此时 CPU 占用量达到了 98.8%,此时我们可以复制该进程 id9,并且使用如下命令查看该进程的各个线程运行情况:

  1. top -Hp 9 

该进程下的各个线程运行情况如下:

  1. top - 08:31:16 up 30 min,  0 users,  load average: 0.75, 0.59, 0.35 
  2. Threads:  11 total,   1 running,  10 sleeping,   0 stopped,   0 zombie 
  3. %Cpu(s):  3.5 us,  0.6 sy,  0.0 ni, 95.9 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st 
  4. KiB Mem:   2046460 total,  1924856 used,   121604 free,    14396 buffers 
  5. KiB Swap:  1048572 total,        0 used,  1048572 free.  1192532 cached Mem 
  6.  
  7.   PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND 
  8.    10 root      20   0 2557160 289824  15872 R 79.3 14.2   0:41.49 java 
  9.    11 root      20   0 2557160 289824  15872 S 13.2 14.2   0:06.78 java 

可以看到,在进程为 9 的 Java 程序中各个线程的 CPU 占用情况,接下来我们可以通过 jstack 命令查看线程 id 为 10 的线程为什么耗费 CPU 最高。

需要注意的是,在 jsatck 命令展示的结果中,线程 id 都转换成了十六进制形式。

(编辑:济南站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读