netty导致tomcat假死

Posted HelloWorld搬运工

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了netty导致tomcat假死相关的知识,希望对你有一定的参考价值。

一、系统需求:

保证后台系统在大并发下正常处理每一个业务连接请求。

二、运作方式:

Netty+tomcat。在tomcat的web.xml配置文件中配置一个Listener类用来在tomcat初始化启动时,启动一个Netty服务端,在Netty服务端的Handler中处理每一个连接请求的复杂业务。

三、使用版本:

netty版本:netty-all-5.0.0.Alpha1

jdk版本:Java: 版本 1.7.0_45

tomcat版本:apache-tomcat-8.0.9

四、运作说明:

使用Netty的高并发性能来处理大量的TCP长连接请求,客户端连接到Netty服务端之后,在Handler中调用web应用中相应的类进行处理。

五、出现问题:

收包一段时间(今天测试五个线程同时发,每个线程发送两万左右的数据包,总共大概十万数据包)以后,就会出现tomcat死机状态,日志了不再有任何输出,运行在同一个tomcat上的其他web工程都不能使用了,为什么由tomcat启动的netty协同工作接收大概十万数据包之后出现tomcat假死状态呢?

六、问题分析:


6.1,监视线程工具1:

jconsole 功能:监控堆内存使用量,线程数,类数量,CPU占用率等. 所在路径:${java安装路径}Javajdk1.8.0_74in

6.2,监视线程工具2:

jvisualvm 功能:同jconsole 所在路径:${java安装路径}Javajdk1.8.0_74in 

jvisualvm监控图:


6.3,dump堆内存文件方法:


方法1、在jvisualvm界面的监视选项卡的,点击“堆 Dump” 按钮即可生成heapdump文件;


方法2、使用命令jmap -dump:format=b,file=HeapDump.bin <pid>生成(会在界面中显示文件路径),需要查看目标线程的pid(可以查看任务管理器,或者在jconsole或者jvisualvm 工具中查看)。


6.4,dump文件分析工具:

MAT(MemoryAnalyzer-1.5.0.20150527-win32.win32.x86_64),打开该软件对6.3中dump出来的dump文件进行分析,可以查看到当前状态下堆内存的使用,以及类的应用情况。


MAT分析结果图:


netty导致tomcat假死

netty导致tomcat假死

netty导致tomcat假死

netty导致tomcat假死

netty导致tomcat假死

得到分析结果DefaultEventExecutor占比较高,可能是其出现问题


6.5,对每一个web应用进行监控(找到问题):


1、将javamelody.jar和jrobin-1.5.9.1.jar两个jar包放到web应用的lib中;


2、在web目录下的web.xml文件中加入如下xml片段。


<!-- tomcat监控 -->

<filter>                

       <filter-name>monitoring</filter-name>                

       <filter-class>net.bull.javamelody.MonitoringFilter</filter-class>         

    </filter>        

<filter-mapping>               

<filter-name>monitoring</filter-name>               

<url-pattern>/*</url-pattern>       

</filter-mapping>       

<listener>                

      <listener-class>net.bull.javamelody.SessionListener</listener-class>        

</listener>


3、在浏览器中访问http://localhost:8080/IoT_Harbor/monitoring?period=jour 即可得到当前web应用的监控图,以及所有线程的当前状态。


4、得到正常运行与异常时的线程状态图:


正常状态时:

netty导致tomcat假死

netty导致tomcat假死

异常时:

5、对比分析正常运行与异常时所有线程状态发现,后端的NIO线程被阻塞,而执行方法为log4j.

七、找到问题:

测试启动的多个线程,每个线程的测试发包速度为50ms,每次收到数据包Netty的Handler线程中均要对接收数据进行日志打印或者控制台输出,会进行频繁的IO操作,而IO操作会相对耗时。Netty的IO处理线程池,如果遇到非常耗时的业务会很容易把后端的NIO线程给挂死、阻塞。

八、解决方法:

对于复杂的后端业务,分派到专门的业务线程池里面,进行异步回调处理。


以上是关于netty导致tomcat假死的主要内容,如果未能解决你的问题,请参考以下文章

利用jvisualvm工具查找tomcat假死问题

连接池连接耗尽导致Tomcat假死的排查心路

rabbitMQ队列处理导致连接池耗尽Tomcat假死问题排查处理

tomcat 假死

Tomcat假死

遇到tomcat的假死问题,如何排查问题