解决java.lang.OutOfMemoryError: unable to create new native thread

Dubbo服务内存溢出,没法建立本地线程问题的解决方案java

异常状况

项目使用Dubbo微服务框架开发后端服务。在服务开启后一小时左右,开始拒绝服务并循环抛出该异常:数据库

com.alibaba.dubbo.remoting.ExecutionException: class com.alibaba.dubbo.remoting.transport.dispatcher.all.AllChannelHandler error when process caught event .

           at com.alibaba.dubbo.remoting.transport.dispatcher.all.AllChannelHandler.caught(AllChannelHandler.java:67)

           at com.alibaba.dubbo.remoting.transport.AbstractChannelHandlerDelegate.caught(AbstractChannelHandlerDelegate.java:44)

           at com.alibaba.dubbo.remoting.transport.AbstractChannelHandlerDelegate.caught(AbstractChannelHandlerDelegate.java:44)

           at com.alibaba.dubbo.remoting.transport.AbstractPeer.caught(AbstractPeer.java:127)

           at com.alibaba.dubbo.remoting.transport.netty.NettyHandler.exceptionCaught(NettyHandler.java:112)

           at com.alibaba.dubbo.remoting.transport.netty.NettyCodecAdapter$InternalDecoder.exceptionCaught(NettyCodecAdapter.java:165)

           at org.jboss.netty.channel.Channels.fireExceptionCaught(Channels.java:432)

           at org.jboss.netty.channel.AbstractChannelSink.exceptionCaught(AbstractChannelSink.java:52)

           at org.jboss.netty.channel.Channels.fireChannelDisconnected(Channels.java:360)

           at org.jboss.netty.channel.socket.nio.NioWorker.close(NioWorker.java:593)

           at org.jboss.netty.channel.socket.nio.NioWorker.read(NioWorker.java:356)

           at org.jboss.netty.channel.socket.nio.NioWorker.processSelectedKeys(NioWorker.java:280)

           at org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:200)

           at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)

           at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)

           at java.lang.Thread.run(Thread.java:745)

Caused by: java.lang.OutOfMemoryError: unable to create new native thread

           at java.lang.Thread.start0(Native Method)

           at java.lang.Thread.start(Thread.java:714)

           at java.util.concurrent.ThreadPoolExecutor.addWorker(ThreadPoolExecutor.java:949)

           at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1360)

           at com.alibaba.dubbo.remoting.transport.dispatcher.all.AllChannelHandler.caught(AllChannelHandler.java:65)

           ... 15 more

问题分析过程

1.        分析异常信息,发现没法建立新的线程;后端

2.        了解微服务部署架构,发现共六个微服务,都部署在一个Tomcat中;bash

3.        打开JDK自带的分析工具,jvisualvm.exe,该程序在JAVA_HOME\bin目录下,载入Tomcat查看线程状况,发现Tomcat的MaxThread设置在800;架构

4.        经过dubbo的status命令,发现服务的线程池配置为固定200个链接,6个服务须要1200个链接,超过了Tomcat的MaxThread,因此Tomcat没法建立新线程;框架

问题缘由与解决方案

项目将Dubbo微服务打包成.war程序,放在Tomcat容器中,借助Tomcat启动微服务,使用Tomcat的JVM。因为放在该Tomcat中的微服务过多,Tomcat的配置知足不了微服务的需求,因此发生了该缘由。socket

一样类似的问题有,在多个微服务中单独使用数据库线程池,链接同一个数据库,形成链接池溢出。微服务

 

解决方法有几种:工具

  1. l   将Dubbo服务使用Dubbo推荐的打包方式,构建成独立的.jar程序,每一个服务单独启动,独享JVM。
  2. l   修改Tomcat的MaxThread知足线程数量要求(不推荐,Tomcat线程数也不是无限的,并且基于操做系统,Window中一个进程能够开启大约2000个线程,Linux中默认一个进行只能开启1000个线程);
  3. l   修改Dubbo的配置,合理设置线程池的驻留线程数量;

相关文章
相关标签/搜索