线上服务CPU100%如何定位

最后更新:2020-04-11

例如线上服务器CPU100%,如何定位问题代码?

  1. top -Hp <pid>找到最耗CPU的线程
# top -Hp 4432
top - 10:55:09 up 583 days, 19:52,  1 user,  load average: 0.08, 0.07, 0.05
Threads:  66 total,   0 running,  66 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.2 us,  0.2 sy,  0.0 ni, 99.7 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem : 32781768 total, 18106528 free,  3529016 used, 11146224 buff/cache
KiB Swap:        0 total,        0 free,        0 used. 28809624 avail Mem 

  PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND                                                                             
 4460 root      20   0 4847588 1.511g  21012 S  0.3  4.8   3:39.28 java                                                                                
 4535 root      20   0 4847588 1.511g  21012 S  0.3  4.8  26:25.14 java                                                                                
 4560 root      20   0 4847588 1.511g  21012 S  0.3  4.8 446:24.02 java                                                                                
 4563 root      20   0 4847588 1.511g  21012 S  0.3  4.8  71:51.63 java                                                                                
19421 root      20   0 4847588 1.511g  21012 S  0.3  4.8  24:59.39 java                                                                                
 4432 root      20   0 4847588 1.511g  21012 S  0.0  4.8   0:00.00 java                                                                                
 4437 root      20   0 4847588 1.511g  21012 S  0.0  4.8   0:13.02 java                                                                                
 4438 root      20   0 4847588 1.511g  21012 S  0.0  4.8   5:08.68 java                                                                                
 4439 root      20   0 4847588 1.511g  21012 S  0.0  4.8   5:07.90 java                                                                                
 4440 root      20   0 4847588 1.511g  21012 S  0.0  4.8   5:07.58 java                                                                                
 4441 root      20   0 4847588 1.511g  21012 S  0.0  4.8   5:07.45 java                                                                                
 4442 root      20   0 4847588 1.511g  21012 S  0.0  4.8   4:42.97 java                                                                                
 4443 root      20   0 4847588 1.511g  21012 S  0.0  4.8   0:00.88 java                                                                                
 4444 root      20   0 4847588 1.511g  21012 S  0.0  4.8   0:00.96 java                                                                                
 4445 root      20   0 4847588 1.511g  21012 S  0.0  4.8   0:00.00 java                                                                                
 4446 root      20   0 4847588 1.511g  21012 S  0.0  4.8   1:59.45 java                                                                                
 4447 root      20   0 4847588 1.511g  21012 S  0.0  4.8   2:05.78 java
  1. 将线程PID转化为16进制
# printf 0x%x 4450
0x1162
  1. jstack查看堆栈
jstack 4432 | grep 0x1162
jstack 4432 | grep -A 10  0x1162 #只看堆栈后面10行

补充点内容:

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

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

相对来说,这是出现频率最高的两种线上问题,而且它们会直接导致系统不可用。另外有几种情况也会导致某个功能运行缓慢,但是不至于导致系统不可用:

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

上述问题都可以通过jstack排查

Edgar

Edgar
一个略懂Java的小菜比