【转】JVM 飙高排查脚本-结构分析
该文章来自于阿里巴巴技术协会(ATA)精选文章。 大家都有过遇到线上程序LOAD突然狂飙的场景,要排查到为何狂飙,我们当务之急就是要找到导致CPU飙升的原因。如果是进程级的应用,如Nginx、Apache等都还比较容易排查,但如果是JVM中的某个线程导致的,估计有人就要开始抓瞎了。
很多人都或多或少的知道有这么一个脚本,能帮你大致定位到现场导致LOAD飙升的JVM线程,脚本大概如下。
#!/bin/ksh
# write by : oldmanpushcart@gmail.com
# date : 2014-01-16
# version : 0.07
typeset top=${1:-10}
typeset pid=${2:-$(pgrep -u $USER java)}
typeset tmp_file=/tmp/java_${pid}_$$.trace
$JAVA_HOME/bin/jstack $pid > $tmp_file
ps H -eo user,pid,ppid,tid,time,{936b63963a8c9f2b24063da536a495a32039ff9ed9d82cacc18dd4741407c351}cpu --sort={936b63963a8c9f2b24063da536a495a32039ff9ed9d82cacc18dd4741407c351}cpu --no-headers\
| tail -$top\
| awk -v "pid=$pid" '$2==pid{print $4"\t"$6}'\
| while read line;
do
typeset nid=$(echo "$line"|awk '{printf("0x{936b63963a8c9f2b24063da536a495a32039ff9ed9d82cacc18dd4741407c351}x",$1)}')
typeset cpu=$(echo "$line"|awk '{print $2}')
awk -v "cpu=$cpu" '/nid='"$nid"'/,/^$/{print $0"\t"(isF++?"":"cpu="cpu"{936b63963a8c9f2b24063da536a495a32039ff9ed9d82cacc18dd4741407c351}");}' $tmp_file
done
rm -f $tmp_file
现在我们就来拆解其中的原理,以及说明下类似脚本的适用范围。
步骤1:dump当前JVM线程,保存现场 $JAVA_HOME/bin/jstack $pid > $tmp_file
步骤2:找到当前CPU使用占比高的线程 ps H -eo user,pid,ppid,tid,time,{936b63963a8c9f2b24063da536a495a32039ff9ed9d82cacc18dd4741407c351}cpu –sort={936b63963a8c9f2b24063da536a495a32039ff9ed9d82cacc18dd4741407c351}cpu
列说明
USER:进程归属用户
PID:进程号
PPID:父进程号
TID:线程号
{936b63963a8c9f2b24063da536a495a32039ff9ed9d82cacc18dd4741407c351}CPU:线程使用CPU占比(这里要提醒下各位,这个CPU占比是通过/proc计算得到,存在时间差)
步骤3:合并相关信息
我们需要关注的大概是3列:PID、TID、{936b63963a8c9f2b24063da536a495a32039ff9ed9d82cacc18dd4741407c351}CPU,我们通过PS拿到了TID,可以通过进制换算10-16得到jstack出来的JVM线程号
typeset nid=”0x”$(echo “$line”|awk ‘{print $1}’|xargs -I{} echo “obase=16;{}”|bc|tr ‘A-Z’ ‘a-z’) 最后再将ps和jstack出来的信息进行一个匹配与合并。终于,得到我们最想要的信息
>> 转载请注明来源:【转】JVM 飙高排查脚本-结构分析免费分享,随意打赏
发表评论