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

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

异常情况

项目使用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中;

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的配置满足不了微服务的需求,所以发生了该原因。

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

 

解决方法有几种:

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

转载于:https://my.oschina.net/u/2450666/blog/1818934

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值