概述
一、发现问题
先看看问题表象:
1、 服务消费者端应用本地保存注册列表异常,报Too many open files
2、 消费者经常出现超时调用的问题
3、
服务消费者端应用出现socket连不上
从上面的问题看出,问题在于
Too many
open
files和
Failed to
open
a
socket
.
4、除了上面的问题。我监控看到的开发环境ESTABLISHED 1万多个,一直连接不释放。通过命令:
先看看问题表象:
1、 服务消费者端应用本地保存注册列表异常,报Too many open files
点击(此处)折叠或打开
- [DubboSaveRegistryCache-thread-1]14:37:30.714 WARN c.a.dubbo.registry.zookeeper.ZookeeperRegistry - [DUBBO] Failed to save registry store file, cause: /data/crm/crmsca/.dubbo/dubbo-registry-132.121.91.184.cache.lock (Too many open files), dubbo version: 2.5.3, current host: 132.121.91.71
- java.io.FileNotFoundException: /data/crm/crmsca/.dubbo/dubbo-registry-132.121.91.184.cache.lock (Too many open files)
- at java.io.RandomAccessFile.open(Native Method) ~[na:1.6.0_35]
- at java.io.RandomAccessFile.<init>(RandomAccessFile.java:216) ~[na:1.6.0_35]
- at com.alibaba.dubbo.registry.support.AbstractRegistry.doSaveProperties(AbstractRegistry.java:187) ~[dubbo-2.5.3.jar:2.5.3]
- at com.alibaba.dubbo.registry.support.AbstractRegistry$SaveProperties.run(AbstractRegistry.java:150) [dubbo-2.5.3.jar:2.5.3]
- at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) [na:1.6.0_35]
- at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) [na:1.6.0_35]
- at java.lang.Thread.run(Thread.java:662) [na:1.6.0_35]
- [DubboSaveRegistryCache-thread-1]14:37:30.715 WARN c.a.dubbo.registry.zookeeper.ZookeeperRegistry - [DUBBO] Failed to load registry store file, cause: /data/crm/crmsca/.dubbo/dubbo-registry-132.121.91.184.cache (Too many open files), dubbo version:2.5.3, current host: 132.121.91.71
2、 消费者经常出现超时调用的问题
点击(此处)折叠或打开
- [DubboSaveRegistryCache-thread-1]14:37:30.714 WARN c.a.dubbo.registry.zookeeper.ZookeeperRegistry - [DUBBO] Failed to save registry store file, cause: /data/crm/crmsca/.dubbo/dubbo-registry-132.121.91.184.cache.lock (Too many open files), dubbo version: 2.5.3, current host: 132.121.91.71
- java.io.FileNotFoundException: /data/crm/crmsca/.dubbo/dubbo-registry-132.121.91.184.cache.lock (Too many open files)
- at java.io.RandomAccessFile.open(Native Method) ~[na:1.6.0_35]
- at java.io.RandomAccessFile.<init>(RandomAccessFile.java:216) ~[na:1.6.0_35]
- at com.alibaba.dubbo.registry.support.AbstractRegistry.doSaveProperties(AbstractRegistry.java:187) ~[dubbo-2.5.3.jar:2.5.3]
- at com.alibaba.dubbo.registry.support.AbstractRegistry$SaveProperties.run(AbstractRegistry.java:150) [dubbo-2.5.3.jar:2.5.3]
- at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) [na:1.6.0_35]
- at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) [na:1.6.0_35]
- at java.lang.Thread.run(Thread.java:662) [na:1.6.0_35]
- [DubboSaveRegistryCache-thread-1]14:37:30.715 WARN c.a.dubbo.registry.zookeeper.ZookeeperRegistry - [DUBBO] Failed to load registry store file, cause: /data/crm/crmsca/.dubbo/dubbo-registry-132.121.91.184.cache (Too many open files), dubbo version:2.5.3, current host: 132.121.91.71
点击(此处)折叠或打开
- [DubboClientReconnectTimer-thread-1]09:57:59.419 ERROR c.a.dubbo.remoting.transport.AbstractClient - [DUBBO] client reconnect to 13
- 2.121.91.179:20883 find error . url: dubbo://132.121.91.179:20883/com.eshore.crm.api.intfmgr.acc.IAccService?anyhost=true&applicatio
- n=crmsca-service&architecture=service&check=false&cityids=N/A&codec=dubbo&connections=100&default.async=false&default.connections=15
- 0&default.proxy=crmProxyFactory&default.retries=0&default.serialization=hessian2&default.service.filter=dstFingerFilter,-default&def
- ault.timeout=60000&default.token=false&dubbo=2.5.3&dynamic=true&heartbeat=60000&interface=com.eshore.crm.api.intfmgr.acc.IAccService
- &ip=132.121.91.70&logger=crm4j&mac=E2:2A:30:C3:52:B8&methods=qryChannel,verifySmsRandomCode,figureVerify,getSmsRandomCode,getReportS
- tate,queryUnifyStaffInfo&monitor=dubbo%3A%2F%2F132.121.91.184%3A7070%3Fdefault%3Dtrue%26dubbo%3D2.5.3%26interface%3Dcom.alibaba.dubb
- o.monitor.MonitorService%26pid%3D16633%26timestamp%3D1442231057363&pid=16633&port=8001&proxy=crmProxyFactory&reference.filter=srcFin
- gerFilter,monitor,-default&retries=0&revision=1.0&serialization=hessian2&side=consumer&timeout=60000×tamp=1442231057352&token=f
- alse, dubbo version: 2.5.3, current host: 132.121.91.70
- com.alibaba.dubbo.remoting.RemotingException: Failed connect to server /132.121.91.179:20883 from NettyClient 132.121.91.70 using dubbo version 2.5.3, cause: Failed to open a socket.
- at com.alibaba.dubbo.remoting.transport.AbstractClient.connect(AbstractClient.java:297) ~[dubbo-2.5.3.jar:2.5.3]
4、除了上面的问题。我监控看到的开发环境ESTABLISHED 1万多个,一直连接不释放。通过命令:
netstat -nat |grep 20880或者使用lsof -i:20880可以检测到。可以看到某些服务都是几千个连接。这个问题在没有上zookeeper 之前是没有这么多连接的。是上了之后才发现的。
二、分析问题
1、分析tcp连接
首先从表象来看,too many open files这个问题网上有很多答案,就是文件句柄数超过了系统设置,系统设置为65535。而linux文件句柄是包含了文件的读写和tcp连接。
可参考:http://langyu.iteye.com/blog/763247
于是,我们用netstat -an | grep port来看一下端口情况:
点击(此处)折叠或打开
- [crmsca@server-91-70 ~]$ netstat -an |grep 20895 | wc -l
- 71854
这时,很容易怀疑的是连接状态是否正常,是否很多CLOSE_WAIT或TIME_WAIT。查看了都是ESTABLISHED状态。
这就奇怪了,几万个连接都是正常的,也不释放。一般http短连接,一个WEB域只有10个以内的连接,200个左右线程处理。
2、分析dubbo的NIO机制
先判断7W个连接都是dubbo的消费者到dubbo提供者之间的。如下图第4
想到dubbo的连接机制与一般http短连接服务不一样,dubbo是NIO的机制。所以研究nio的机制。
关于nio的Reactor模式参考:http://ryanflyer.iteye.com/blog/1672876
本来认为可能是因为后端服务慢,导致前端请求阻塞。分析Rector后发现,只有一条长连接。其它都是线程池处理。为什么连接数会这么多呢?原来dubbo协议是单一长连接的协议,是不会释放的。参考:http://blog.csdn.net/freebird_lb/article/details/7303235
dubbo可以支持dubbo、http、rmi等多种协议,而Dubbo缺省协议采用单一长连接和NIO异步通讯,适合于小数据量大并发的服务调用,以及服务消费者机器数远大于服务提供者机器数的情况。
3、分析dubbo的长连接机制
参考网上的dubbo问题: http://www.52ml.net/7601.html ,和我们生产现象也不一样。
查看配置发现dubbo配置每个服务提供者都是配置连接数为100或150的。
而提供者有100个,加上dubbo的集群,就有200个提供者。消费者是比提供者多的,而且还会增多。
而且生产不是延迟加载,那么有一个消费者加进来。就会增加100个连接。这样累加起来,就有几万个了。
因此需要验证以下想法:
1、减少服务连接,是否可以减少TCP连接数。
2、连接数是否会由于消费者的增加而成倍增加。
通过验证发现,1、TCP连接数会减少 2、会成倍增加
而连接与线程数不是一个概念。所以连接数10以下就可以,线程数一般100到300,由线程池管理。
而连接与线程数不是一个概念。所以连接数10以下就可以,线程数一般100到300,由线程池管理。
点击(此处)折叠或打开
- 缺省协议,使用基于mina1.1.7+hessian3.2.1的tbremoting交互。
- 连接个数:单连接
- 连接方式:长连接
- 传输协议:TCP
- 传输方式:NIO异步传输
- 序列化:Hessian二进制序列化
- 适用范围:传入传出参数数据包较小(建议小于100K),消费者比提供者个数多,单一消费者无法压满提供者,尽量不要用dubbo协议传输大文件或超大字符串。
- 适用场景:常规远程服务方法调用
- 为什么要消费者比提供者个数多:
- 因dubbo协议采用单一长连接,
- 假设网络为千兆网卡(1024Mbit=128MByte),
- 根据测试经验数据每条连接最多只能压满7MByte(不同的环境可能不一样,供参考),
- 理论上1个服务提供者需要20个服务消费者才能压满网卡。
参考dubbo官网资料: http://dubbo.io/User+Guide-zh.htm
三、解决问题。
问题原因:
1、官网建议在Provider上尽量多配置Consumer端属性,而生产上设置是没有这样做的,导致客户端的配置以服务提供者为准 。
2、Provider上配置 合理的Provider端属性。而生产上也没有这样做,没有对总的dubbo做连接数限制。所以导致连接数爆了。
3、连接数设置不合理,设置过大 。一个连接可以同时处理10个、100个并发都是没有问题的。
4、未设置延迟加载,导致tcp长连接浪费。
解决方法:
1、先减少连接数为10观察,后续一般服务 减 少 到 2 ,大并发服务设置为10。
2、使用延迟加载配置。
四、总结
1、连接数和并发数、线程数不是一个概念。连接数是与网络连接有关的。一个连接数可以支持70Mbype的网络流量。
多个并发请求是在一个tcp连接上传输的。传输到达dubbo端后,dubbo会把tcp连接上的请求分配给线程池中的线程处理。
2、长连接是一直占用的网络连接,线程会超时,而长连接不会断开。
3、nio rector机制通过长连接来减少tcp握手和挥手的开销。通过事件通知来实现非阻塞式传输,因些阻塞不会传递。
最后
以上就是冷酷飞机为你收集整理的dubbo连接池爆满,一直ESTABLISHED 连接的全部内容,希望文章能够帮你解决dubbo连接池爆满,一直ESTABLISHED 连接所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复