例如线上服务器CPU100%,如何定位问题代码?
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
- 将线程PID转化为16进制
# printf 0x%x 4450
0x1162
- jstack查看堆栈
jstack 4432 | grep 0x1162
jstack 4432 | grep -A 10 0x1162 #只看堆栈后面10行
补充点内容:
对于线上系统突然产生的运行缓慢问题,如果该问题导致线上系统不可用,那么首先需要做的就是,导出jstack和内存信息,然后重启系统,尽快保证系统的可用性。这种情况可能的原因主要有两种:
- 代码中某个位置读取数据量较大,导致系统内存耗尽,从而导致Full GC次数过多,系统缓慢;
- 代码中有比较耗CPU的操作,导致CPU过高,系统运行缓慢;
相对来说,这是出现频率最高的两种线上问题,而且它们会直接导致系统不可用。另外有几种情况也会导致某个功能运行缓慢,但是不至于导致系统不可用:
- 代码某个位置有阻塞性的操作,导致该功能调用整体比较耗时,但出现是比较随机的;
- 某个线程由于某种原因而进入WAITING状态,此时该功能整体不可用,但是无法复现;
- 由于锁使用不当,导致多个线程进入死锁状态,从而导致系统整体比较缓慢。
上述问题都可以通过jstack排查