最难的是认识自己!个人网站,欢迎访问!前言:最近测试部的同事来找我说,他们在测试的时候,发现服务接口请求有一段时间没有响应了。Tomcat好像死了,并没有返回任何错误响应。让我快速检查一下;我一听,瞬间惊呆了,姐姐,最近总是出问题,领导要给我开批评会。哈哈,开玩笑的,我这么帅的人,领导怎么忍心批评我,哼哼,我马上解决这个问题,不让领导知道!简单说一下程序部署:tomcat+oracle排查过程:排查时可以使用命令排查,也可以使用可视化监控工具;例如使用JDK自带的jvisualvm.exe监控工具。命令故障处理过程:1.请求的服务无响应。首先查看tomcat是否真的宕机:命令:ps-ef|greptomcat通过以上命令查看tomcat是否正在运行;执行结果如下:注意:如果服务器正在运行如果有多个tomcat在运行,需要检查下图框内运行的tomcat的地址是否正确;通过命令检查,发现tomcat运行正常,那么这个就处于假死状态,接下来就是检查了。2、查看http请求是否到达tomcat:查看tomcat的logs目录下localhost_access_log日志文件中的请求记录;command:tail-100flocalhost_access_log通过上面的命令查看实时日志,执行上面的命令查看日志后,再请求程序,在日志中没有发现请求记录,说明tomcat处于状态假死了,下一步就是检查了。3、查看tomcat的JVM的GC状态:查看GC状态,是否因为频繁GC或者长时间GC导致程序长时间卡顿,最终请求来不及处理,而它进入队列等待,调用者长时间无响应,导致tomcat假死;命令:jstat-gcpidtimecount例如:jstat-gc7112910005监控71129进程的JVMGC状态,每1000ms输出一次,共输出5次;命令执行结果参数分析:通过上述命令查看GC情况,发现垃圾回收不频繁,GC时间不长,应该不是GC的原因。4、查看tomcat的JVM堆状态:查看堆内存状态,是否存在堆内存溢出导致tomcat卡死,无法为新的请求分配堆内存资源;命令:jmap-heappid例子:jmap-heap7112971129正在运行的tomcat进程号;从命令执行结果来看,堆内存中可用内存还是很大的,不会出现内存溢出问题,所以不是堆内存小导致的tomcat假死。5、查看tomcat的JVM线程状态:①使用jstack命令导出当前JVM的threaddump快照,然后查看dump中的线程在做什么?命令:jstackpid>>jvmThreadDump.log示例:jstack71129>>jvmThreadDump.log生成71129进程的JVM线程快照,并将快照内容重定向到jvmThreadDump.log文件;注意:生成的jvmThreadDump.log在你当前执行命令的目录中。②、然后使用命令more查看jvmThreadDump.log的内容;command:morejvmThreadDump.log如果dump文件太大,需要使用more命令稍微查看一下;执行more命令后,按回车键显示文件内容;③.通过查看线程快照文件,发现很多线程的状态都是WAITING;并使用命令查看线程状态为WAITING的线程占总线程的比例:注意:tomcatDump.log是生成的线程快照文件的名字,记得改成自己设置的名字;计数=`cattomcatDump.log|grepjava.lang.线程状态|wc-l`;等待=`cattomcatDump.log|正在等待|wc-l`;一个=`回声|awk"{print$wait/$count*100}"`;echo"$a%"执行命令,结果为:91.9786%,发现90%以上的线程处于等待状态;至此,tomcat假死的原因找到了,但还需要进一步确定是什么原因导致大量线程等待?通过查看调用的服务接口的代码,我知道我在这个接口的业务逻辑上没有设置任何锁,所以我写的代码应该没有问题,但是这个接口涉及到很多JDBC数据库操作.它在数据库连接池中吗?连接不够?因为数据库连接是竞争资源,如果连接池中的连接已经用完,那么下一个JDBC线程就需要等待连接。6、查看与数据库建立的TCP连接:上面发现有大量线程处于等待状态,但通过分析,可能是数据库连接池中的连接耗尽导致的,可以查看通过命令部署服务,代码服务器与数据库所在服务器建立的TCP连接数是否达到配置的数据库连接池中的最大连接数;命令:netstat-pan|grep1521|wc-l因为本文使用的数据库是Oracle,所以grep搜索匹配的端口号是1521;如果是mysql数据库,把端口号改成3306,netstat-pan|grep3306|wc-l;如果设置了自定义数据库端口号,将其更改为自定义端口号即可;通过命令查询,已经使用的数据库连接数为6,然后查看数据库连接池集合中的最大连接数;数据源配置如下:
