JAVA环境的CPU高负载问题排查小计
作者:互联网
JAVA环境的CPU高负载问题排查小计
赵阳 360云计算
女主宣言
目前互联网公司的web环境大部分还是以LNMP为主,php更多时候还是做为web服务端开发的首选。做为运维工程师排查php方面的问题相信大家都是信手拈来,但是在面对JAVA这种“高冷”的环境时,相信还是有很多同学会显得束手无策。今天就为大家分享一篇简单的JAVA环境trouble shooting的小技巧。
PS:丰富的一线技术、多元化的表现形式,尽在“HULK一线技术杂谈”,点关注哦!
背景简介
目前互联网公司的web开发基本都是使用PHP,在web领域PHP还是拥有得天独厚的优势,简单易用、并且拥有众多粉丝的它已经占据了web领域的半壁江山。而JAVA更多时候还是做为电信、金融等领域的首选。
然而做为运维人员,也因行业的不同,专注的技术领域也有所不同,毕竟大多数同学还是在“php当家的”互联网公司就职,在排查JAVA环境的问题时,很多同学都是经验不足,从而显得有些“懵B”。相信在看完这篇文章之后,大家都能永远的告别“懵B的自己”。
1
场景
某个业务的WEB服务端是JAVA环境的,一天收到了大量的CPU_idle报警,登录服务器排查发现是JAVA进程占用CPU较高所致,而且该问题属于断断续续这种。
具体情况如下图:
可以看到该主机的CPU使用率已经接近满负荷。
2
问题分析
根据问题定位:CPU占用过高是JAVA进程,属于tomcat服务,tomcat一般出现问题都是full GC之类的内存问题,占用CPU过高大致可以定位是代码层出现问题,导致占用CPU过高。
3
使用jstack定位问题
jstack介绍:
jstack是一个堆栈跟踪工具,主要用于打印指定Java进程、核心文件或远程调试服务器的Java线程的堆栈跟踪信息。
用法:
jstack [ option ] <pid> //指定进程号(pid)的进程#指定核心文件
jstack [ option ] <executable <core> //指定核心文件
jstack [ option ] [server-id@]<remote-hostname-or-IP> //指定远程调试服务器
常用参数:
pid: java应用程序的进程号,一般可以通过jps来获得;
executable:产生core dump的java可执行程序;
core:打印出的core文件;
remote-hostname-or-ip:远程debug服务器的名称或IP;
server-id: 唯一id,假如一台主机上多个远程debug服务;
基本参数:
-l //长列表. 打印关于锁的附加信息,例如属于java.util.concurrent的ownable synchronizers列表
-F //当’jstack [-l] pid’没有相应的时候强制打印栈信息
-m //打印java和native c/c++框架的所有栈信息
pid //需要被打印配置信息的java进程id,可以用jps查询
方法
用命令查看比较占用CPU非常高的线程的id,图中主进程id是10832,问题线程id是11358。
细节:
1.也可以使用ps -mp $PID -o THREAD,tid,time | sort -k 2 -r | head -20来查看线程运行情况。
2.jstack内部的进程号是16进制的,所以要将线程id转换成16进制
$ echo "obase=16;11358" | bc
$ 2C5E
jstack抓取日志,jstack -l 10832,经过判断为正则表达式匹配导致CPU过高。
如图:
扩展
Jstat
这是一个比较实用的一个命令,可以观察到classloader,compiler,gc相关信息。可以时时监控资源和性能。
命令格式
-class //统计class loader行为信息
-compile //统计编译行为信息
-gc //统计jdk gc时heap信息
-gccapacity //统计不同的generations(不知道怎么翻译好,包括新生区,老年区,permanent区)相应的heap容量情况
-gccause //统计gc的情况,(同-gcutil)和引起gc的事件
-gcnew //统计gc时,新生代的情况
-gcnewcapacity //统计gc时,新生代heap容量
-gcold //统计gc时,老年区的情况
-gcoldcapacity //统计gc时,老年区heap容量
-gcpermcapacity //统计gc时,permanent区heap容量
-gcutil //统计gc时,heap情况
Jmap
得到运行java程序的内存分配的详细情况。例如实例个数,大小等。
命名行格式
jmap [ option ] pid
jmap [ option ] executable core
jmap [ option ] [server-id@]remote-hostname-or-IP
-dump:[live,]format=b,file=<filename> //使用hprof二进制形式,输出jvm的heap内容到文件=. live子选项是可选的,假如指定live选项,那么只输出活的对象到文件.
-finalizerinfo //打印正等候回收的对象的信息.
-heap //打印heap的概要信息,GC使用的算法,heap的配置及wise heap的使用情况.
-histo[:live] //打印每个class的实例数目,内存占用,类全名信息. VM的内部类名字开头会加上前缀”*”. 如果live子参数加上后,只统计活的对象数量.
-permstat //打印classload和jvm heap长久层的信息. 包含每个classloader的名字,活泼性,地址,父classloader和加载的class数量. 另外,内部String的数量和占用内存数也会打印出来.
-F //强迫.在pid没有相应的时候使用-dump或者-histo参数. 在这个模式下,live子参数无效.
-h | -help //打印辅助信息
-J //传递参数给jmap启动的jvm.
标签:JAVA,jstack,小计,id,gc,heap,CPU 来源: https://blog.51cto.com/15127564/2668208