dubbo连接池爆满,一直ESTABLISHED 连接

一、发现问题
        先看看问题表象:
       1、 服务消费者端应用本地保存注册列表异常,报Too many open files
       

点击(此处)折叠或打开

  1. [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
  2. java.io.FileNotFoundException: /data/crm/crmsca/.dubbo/dubbo-registry-132.121.91.184.cache.lock (Too many open files)
  3.         at java.io.RandomAccessFile.open(Native Method) ~[na:1.6.0_35]
  4.         at java.io.RandomAccessFile.<init>(RandomAccessFile.java:216) ~[na:1.6.0_35]
  5.         at com.alibaba.dubbo.registry.support.AbstractRegistry.doSaveProperties(AbstractRegistry.java:187) ~[dubbo-2.5.3.jar:2.5.3]
  6.         at com.alibaba.dubbo.registry.support.AbstractRegistry$SaveProperties.run(AbstractRegistry.java:150) [dubbo-2.5.3.jar:2.5.3]
  7.         at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) [na:1.6.0_35]
  8.         at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) [na:1.6.0_35]
  9.         at java.lang.Thread.run(Thread.java:662) [na:1.6.0_35]
  10. [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、 消费者经常出现超时调用的问题

点击(此处)折叠或打开

  1. [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
  2. java.io.FileNotFoundException: /data/crm/crmsca/.dubbo/dubbo-registry-132.121.91.184.cache.lock (Too many open files)
  3.         at java.io.RandomAccessFile.open(Native Method) ~[na:1.6.0_35]
  4.         at java.io.RandomAccessFile.<init>(RandomAccessFile.java:216) ~[na:1.6.0_35]
  5.         at com.alibaba.dubbo.registry.support.AbstractRegistry.doSaveProperties(AbstractRegistry.java:187) ~[dubbo-2.5.3.jar:2.5.3]
  6.         at com.alibaba.dubbo.registry.support.AbstractRegistry$SaveProperties.run(AbstractRegistry.java:150) [dubbo-2.5.3.jar:2.5.3]
  7.         at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) [na:1.6.0_35]
  8.         at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) [na:1.6.0_35]
  9.         at java.lang.Thread.run(Thread.java:662) [na:1.6.0_35]
  10. [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
          3、 服务消费者端应用出现socket连不上

点击(此处)折叠或打开

  1. [DubboClientReconnectTimer-thread-1]09:57:59.419 ERROR c.a.dubbo.remoting.transport.AbstractClient - [DUBBO] client reconnect to 13
  2. 2.121.91.179:20883 find error . url: dubbo://132.121.91.179:20883/com.eshore.crm.api.intfmgr.acc.IAccService?anyhost=true&applicatio
  3. n=crmsca-service&architecture=service&check=false&cityids=N/A&codec=dubbo&connections=100&default.async=false&default.connections=15
  4. 0&default.proxy=crmProxyFactory&default.retries=0&default.serialization=hessian2&default.service.filter=dstFingerFilter,-default&def
  5. ault.timeout=60000&default.token=false&dubbo=2.5.3&dynamic=true&heartbeat=60000&interface=com.eshore.crm.api.intfmgr.acc.IAccService
  6. &ip=132.121.91.70&logger=crm4j&mac=E2:2A:30:C3:52:B8&methods=qryChannel,verifySmsRandomCode,figureVerify,getSmsRandomCode,getReportS
  7. tate,queryUnifyStaffInfo&monitor=dubbo%3A%2F%2F132.121.91.184%3A7070%3Fdefault%3Dtrue%26dubbo%3D2.5.3%26interface%3Dcom.alibaba.dubb
  8. o.monitor.MonitorService%26pid%3D16633%26timestamp%3D1442231057363&pid=16633&port=8001&proxy=crmProxyFactory&reference.filter=srcFin
  9. gerFilter,monitor,-default&retries=0&revision=1.0&serialization=hessian2&side=consumer&timeout=60000&timestamp=1442231057352&token=f
  10. alse, dubbo version: 2.5.3, current host: 132.121.91.70
  11. 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.
  12.         at com.alibaba.dubbo.remoting.transport.AbstractClient.connect(AbstractClient.java:297) ~[dubbo-2.5.3.jar:2.5.3]
         从上面的问题看出,问题在于 Too many  open  files和  Failed to  open  a  socket .
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来看一下端口情况:
   

点击(此处)折叠或打开

  1. [crmsca@server-91-70 ~]$ netstat -an |grep 20895 | wc -l
  2. 71854
 可以看到,dubbo服务有7W多个连接。而系统设置ulimit -n 的值 65535,所以是有可能把连接爆掉的。
 这时,很容易怀疑的是连接状态是否正常,是否很多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,由线程池管理。

点击(此处)折叠或打开

  1. 缺省协议,使用基于mina1.1.7+hessian3.2.1的tbremoting交互。

  2. 连接个数:单连接
  3. 连接方式:长连接
  4. 传输协议:TCP
  5. 传输方式:NIO异步传输
  6. 序列化:Hessian二进制序列化
  7. 适用范围:传入传出参数数据包较小(建议小于100K),消费者比提供者个数多,单一消费者无法压满提供者,尽量不要用dubbo协议传输大文件或超大字符串。
  8. 适用场景:常规远程服务方法调用
  9. 为什么要消费者比提供者个数多:
  10. 因dubbo协议采用单一长连接,
  11. 假设网络为千兆网卡(1024Mbit=128MByte)
  12. 根据测试经验数据每条连接最多只能压满7MByte(不同的环境可能不一样,供参考)
  13. 理论上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,连接不释放,dubbo,很多ESTABLISHED)