整了个脚本,希望以后cpu高的时候,能够一键定位~~~~
郑重声明:参数要根据自身业务调整,线上执行jstack 要谨慎,本文只提供demo, 不作为线上操作标准。由于操作失误产生的后果由使用方自己完全负责哈~~~
1 用法:
(1)scmp 登录机器
(2)创建getCpuUsageOfJavaThread.sh 文件。
vi getCpuUsageOfJavaThread.sh
(3) 将如下代码copy进 getCpuUsageOfJavaThread.sh
#!/bin/bashecho "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~welcom~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"echo "usage: sh getCpuUsageOfJavaThread.sh sleepTime execCount cpuUsageThreshold"echo "eg: sh getCpuUsageOfJavaThread.sh 20 5 1 -- every 20s execute jstack once, and all execute 5 times . if cpu usage bigger than 1% while print"echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~gogogo~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"sleepTime=$1execCount=$2cpuUsageThreshold=$3if [ ! -n "$1" ] ;thenecho "param sleepTime is null"echo "eg: sh getCpuUsageOfJavaThread.sh 20 5 1 -- every 20s execute jstack, and execute 5 times all. if cpu usage bigger than 1% while print"exitfiif [ ! -n "$2" ] ;thenecho "param execCount is null"echo "eg: sh getCpuUsageOfJavaThread.sh 20 5 1 -- every 20s execute jstack, and execute 5 times all. if cpu usage bigger than 1% while print"exitfiif [ ! -n "$3" ] ;thenecho "param cpuUsageThreshold is null"echo "eg: sh getCpuUsageOfJavaThread.sh 20 5 1 -- every 20s execute jstack, and execute 5 times all. if cpu usage bigger than 1% while print"exitfiif [ ! -d "cpuData" ]; thenmkdir cpuDataficd cpuDatan=0while (($n<$execCount))do#获取cpu使用大于sleepTime% 的 java 线程:now=$(date "+%Y%m%d-%H%M%S")mkdir ${now}cd ${now}javapid=$(jps | grep "jar" | awk '{print $1}')&&ps H -e -o pid,tid,pcpu,args --sort=-pcpu | awk -v jpid="$javapid" -v cpuUsageThreshold="$cpuUsageThreshold" '{if ($1 == jpid && $3 > cpuUsageThreshold) print $0}' > ${now}_threadCpuGT${cpuUsageThreshold}awk '{print $2,$3}' ${now}_threadCpuGT${cpuUsageThreshold} > ${now}_threadIdjstack ${javapid} > ${now}_fullstackInfowhile read tid_cpu;do# 将线程转换为十六进制tid=`echo $tid_cpu | awk '{print $1}'`cpu=`echo $tid_cpu | awk '{print $2}'`threadId16=$(printf "0x%x\n" ${tid})echo "================= 线程id为 threadId-${tid}, 对应十六进制为 ${threadId16} , cpu使用率为 ${cpu} %. 详细堆栈信息如下 :=================" >> ${now}_final_result#grep -A 30 "nid="${threadId16}" " ${now}_fullstackInfo >> ${now}_final_resultsed -n -e "/nid=${threadId16} /, /^$/ p" ${now}_fullstackInfo >> ${now}_final_resultdone < ${now}_threadIdrm ${now}_threadCpuGT${cpuUsageThreshold}rm ${now}_threadId#执行次数加一n=$((n+1))echo "=========execute ${n} times========="# sleep 几秒sleep $sleepTime# 跳出一层,方便执行下一次cd ..doneecho "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ have a good time, bye ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
(4)执行如下指令:
郑重声明:参数要根据自身业务调整,线上执行jstack 要谨慎,本文只提供demo, 不作为线上操作标准。由于操作失误产生的后果由使用方自己完全负责哈~~~
demo :
sh getCpuUsageOfJavaThread.sh 20 5 1
表示: 每20秒执行一次 ps 跟 jstack , 总共执行5次,会选择cpu 使用大于1% 的线程进行进行输出。
(5)结果文件说明:
文件夹路径: cd cpuData/xxxxxx-yy (相对于getCpuUsageOfJavaThread.sh 文件所在的目录)
20201204-062028_final_result 为 展示线程,以及对应的cpu使用率 的最终结果文件。20200303-172806_fullstackInfo jstack 完全堆栈信息
图片示例:
结果实例:
