argus(阿格斯) 报警cpu占用100%,立马使用常规定位方法:
1, top -H-p命令找出cpu占用最高的进程
2,jsp -l 进一步定位出进程编号
3,ps -mp <进程号> -o thread,tid,time 定位出具体线程
发现进程下的线程资源占比根本就不高,因此不能定位到具体线程的堆栈信息,怀疑是在做FULL GC,查看进程GC回收情况
jstat -gcutil <进程号> 3000
回收正常,定位不到问题,只能等到下一次报警再打印堆栈信息
jstack -l <进程号> > /<输出的文件名称>
将进程号转成16进制,在文件中搜索
确定是在做GC回收导致的cpu占比100%,立即用jmap命令输出加载类的内存占用情况
jmap -histo:live <进程号> > /<输出的文件名>
定位到具体的数据表对象,全量查表信息将内存打满,触发FULL GC,但具体是那个子业务那段逻辑引发的,需要写个shell脚本,找出对应线程号
#!/bin/bash
cd /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.232.b09-0.el7_7.x86_64/bin
APP_PID_TEMP=$(./jps -l | grep wom )
eval "$(echo "$APP_PID_TEMP" | awk '{ printf("pid=%s;pidname=%s",$1,$2)}')"
echo "加载的项目是$pidname,进程ID是: $pid"
APP_PID=$pid
topJavaId=`top -b -n 1 -Hp ${APP_PID}|grep java|head -n 1|awk '{print $1}'`
cpuUsage=`top -b -n 1 -Hp ${APP_PID}|grep java|head -n 1|awk '{print $9}'`
echo "最耗cpu的使用率为 $cpuUsage"
topJavaId16=`printf "%x" ${topJavaId}`
topJavaId16ThreadName="nid=0x${topJavaId16}"
echo "最耗cpu的java线程ID 16进制为 $topJavaId16ThreadName"
threadDetail=`./jstack ${APP_PID}|grep ${topJavaId16} -C 10`
echo Thread Detial "$threadDetail"
或者拼手速
1, top -H -p 命令找出cpu占用最高的进程
2,jps -l 进一步定位出进程编号
3,ps -mp <进程号> -o thread,tid,time 定位出具体线程 耗时最多的即是有问题的线程
4,线程Id 转为16进制(linux 中输出的为10进制)
5,打印内存信息 jstack <进程id> | grep 小写16进制线程id -A60
即能够定位出具体代码位置