线上故障排查:CPU占用率较高

参考:http://t.cn/Ai8tKbfM

一、方法一

第一步:找到占用CPU过高的进程的pid

使用top命令,然后按shift+p按照CPU排序

第二步:找到进程中消耗资源最高的线程的id

使用top -Hp [进程id]

第三步:将线程id转换为16进制(字母要小写)

使用echo 'obase=16;[线程id]' | bc或者printf "%x\n" [线程id]
【bc是linux的计算器命令】

第四步:查看线程状态信息

执行jstack [进程id] |grep -A 10 [线程id的16进制]”

第五步:导出dump信息

执行jstack [进程id] |grep -A 10 [线程id的16进制] > xxx.txt
下载至本地sz xxx.txt


二、方法二

第一步:找到占用CPU过高的进程

使用top命令,然后按shift+p按照CPU排序

第二步:获取线程信息,并找到占用CPU高的线程

使用ps -mp pid -o THREAD,tid,time | sort -rn

第三步:.将需要的线程ID转换为16进制格式

使用echo 'obase=16;[线程id]' | bc或者printf "%x\n" [线程id]

第四步:打印线程的堆栈信息

使用jstack pid |grep tid -A 30 [线程id的16进制]

第五步:导出dump信息

执行jstack [进程id] |grep -A 10 [线程id的16进制] > xxx.txt
下载至本地sz xxx.txt

三、案例分析

1. 场景描述

生产环境下JAVA进程高CPU占用故障排查

2. 解决过程

(1) 根据top命令,发现PID为8540的Java进程占用CPU高达300%,出现故障。

# top |grep java 
PID  USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
8495 root      20   0 3024772 247164    164 S   300.6 12.3   0:08.62 java

(2) 找到该进程后,如何定位具体线程或代码呢,首先显示线程列表,并按照CPU占用高的线程排序:

# ps -mp 8495 -o THREAD,tid,time | sort -rn

显示结果如下:

USER     %CPU PRI SCNT WCHAN  USER SYSTEM    TID     TIME
root      30.2   -    - -         -      -      8507 00:12:40

找到了耗时***的线程(TID)8507,占用CPU时间有12分钟了!

(3) 将需要的线程TID转换为16进制格式

# printf "%x\n" 8507
213b

(4) 使用jstack命令打印出该进程下面的此线程的堆栈信息:

# jstack 8495 |grep -A 5 213b

"http-nio-9000-AsyncTimeout" #29 daemon prio=5 os_prio=0 tid=0x00007fb96c97f000 nid=0x215c waiting on condition [0x00007fb91aff0000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
    at java.lang.Thread.sleep(Native Method)
    at org.apache.coyote.AbstractProtocol$AsyncTimeout.run(AbstractProtocol.java:1211)
    at java.lang.Thread.run(Thread.java:748)

(5)导出堆栈信息

# jstack 8495 |grep -A 5 213b > 8495.txt
# sz 8495.txt

你可能感兴趣的:(线上故障排查:CPU占用率较高)