dubbo连接池爆满

博客内容讲述了在使用Dubbo时遇到的问题,具体表现为由于打开的文件过多导致连接池满,出现`Too many open files`错误。错误出现在尝试保存Dubbo注册中心缓存文件时,同时客户端重连服务端也失败,提示无法建立连接。通过`netstat`命令检查到大量连接处于活动状态。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、发现问题
        先看看问题表象:
       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 .


二、分析问题

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.youkuaiyun.com/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握手和挥手的开销。通过事件通知来实现非阻塞式传输,因些阻塞不会传递。
<think>好的,用户现在遇到了Dubbo连接池爆满的问题,需要解决方案。首先,我得回顾一下Dubbo连接池的相关知识。Dubbo默认使用Netty作为通信框架,连接池的管理可能涉及客户端和服务端的线程池配置。根据用户提供的引用,特别是引用[1]、[4]提到线程池占满的情况,可能的原因包括外部调用阻塞(如HttpClient)、异步编程问题(如CompletableFuture)以及GC STW等。 首先需要分析连接池爆满的具体原因。可能的常见原因包括:服务处理时间过长导致线程无法及时释放,资源泄漏(如未正确关闭连接),外部依赖响应慢,或者配置不合理(如线程池大小不足)。引用[3]提到创建connectionPool的方法,可能配置不当也是一个因素。 解决方案方面,可以从以下几个方面入手: 1. **调整线程池配置**:增加线程数,但需注意不能无限制增加,需根据系统资源进行调整。Dubbo允许设置不同的线程池类型,比如fixed(固定大小)或cached(缓存),可能需要调整类型和参数。 2. **优化服务性能**:减少服务方法的执行时间,避免长时间阻塞操作,比如同步调用外部服务或数据库查询过慢。可以考虑异步化处理或优化业务逻辑。 3. **排查资源泄漏**:检查是否有未正确释放的连接或资源,比如未关闭的流、未返回的响应等。引用[2]提到连接失败的问题,可能和socket未正确释放有关,需要检查网络配置和连接管理。 4. **设置超时和降级**:合理设置服务调用的超时时间,避免线程长时间等待。同时,使用熔断降级机制,防止故障扩散。 5. **监控和日志分析**:通过Dubbo的监控接口或日志,查看线程堆栈,确定线程阻塞的位置。引用[4]中提到的排查过程,可能需要在线日志或线程Dump分析。 6. **使用异步调用**:将同步调用改为异步,比如使用CompletableFuture,但需注意正确使用,避免因回调未处理导致线程池占满,如引用[1]中的第二次问题。 另外,用户提供的引用中有提到HttpClient可能导致的问题,需要注意在Dubbo服务中是否有使用同步的HTTP客户端调用,导致线程阻塞。这种情况下,可以替换为异步客户端或调整调用方式。 需要确保所有配置项正确,比如连接超时时间、重试次数等。同时,检查是否有频繁的GC导致线程暂停,如引用[1]的第三次问题,可能需要优化JVM参数或减少内存泄漏。 总结下来,解决方案需要结合配置调整、代码优化、资源管理和监控分析。用户需要逐步排查可能的原因,从调整线程池大小开始,优化服务响应时间,设置合理的超时,并加强监控以便快速定位问题源。</think>### Dubbo 连接池爆满解决方案 #### 1. **优化线程池配置** - **调整线程池类型**:Dubbo 默认使用固定大小的线程池(`fixed`),可尝试切换为缓存线程池(`cached`)或有限线程池(`limited`)以适应突发流量。例如: ```xml <dubbo:protocol name="dubbo" threadpool="cached" threads="200" /> ``` - **增大核心线程数**:根据业务负载合理设置线程数上限,避免因线程不足导致阻塞[^1]。 #### 2. **减少服务阻塞时间** - **优化业务逻辑**:检查服务方法是否存在慢查询、同步 I/O 操作(如文件读写或 HTTP 调用),尝试异步化或优化算法。 - **拆分耗时操作**:将耗时任务与核心逻辑分离,通过消息队列异步处理。 #### 3. **设置合理超时与重试** - **配置超时时间**:在服务提供者和消费者端设置超时(单位:毫秒),避免无限等待: ```xml <dubbo:service timeout="3000" /> <dubbo:reference timeout="3000" /> ``` - **限制重试次数**:减少因网络波动导致的无效重试: ```xml <dubbo:reference retries="2" /> ``` #### 4. **排查资源泄漏** - **检查连接未关闭**:确保数据库连接、HTTP 客户端等资源使用后正确释放。例如 HttpClient 需调用 `close()`[^3]。 - **分析线程堆栈**:通过 `jstack` 或 Arthas 生成线程快照,定位阻塞位置。常见问题包括: - 同步调用第三方服务未设置超时。 - 锁竞争或死锁。 #### 5. **熔断与降级机制** - **集成熔断框架**:使用 Sentinel 或 Hystrix 实现自动熔断,当错误率超过阈值时快速失败。 - **服务降级策略**:非核心功能降级为默认返回值,释放线程资源。 #### 6. **监控与告警** - **启用 Dubbo QOS**:通过 Telnet 或 HTTP 端口实时查看线程池状态(如 `ls` 命令)。 - **日志监控**:对线程池满的异常日志(如 `Thread pool is EXHAUSTED`)配置告警[^4]。 --- ### 案例分析 - **案例 1**:某系统因同步调用 HttpClient 未设置超时,导致线程池占满。优化方案为改用异步 HttpClient 并设置超时。 - **案例 2**:GC STW 引发线程池满,通过优化 JVM 参数(如调整堆大小、更换低停顿垃圾回收器)解决[^1]。 ---
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值