Dubbo超时机制导致的雪崩连接
Bug影响:Dubbo服务提供者出现无法获取Dubbo服务处理线程异常,后端DB爆出拿不到数据库连接池,导致前端响应时间异常飙高,系统处理能力下降,核心基础服务无法提供正常服务。
Bug发现过程:
线 上,对于高并发的服务化接口应用,时常会出现Dubbo连接池爆满情况,通常,我们理所应当的认为,这是客户端并发连接过高所致,一方面调整连接池大小, 一方面考虑去增加服务接口的机器,当然也会考虑去优化服务接口的应用。很自然的,当我们在线上压测一个营销页面(为大促服务,具备高并发)时,我们遇到了 这种情况。而通过不断的深入研究,我发现了一个特别的情况。
场景描述:

压力从Jmeter压至前端web应用marketingfront,场景是批量获取30个产品的信息。wsproductreadserver有一个批量接口,会循环从tair中获取产品信息,若缓存不存在,则命中db。
压测后有两个现象:
1)Dubbo的服务端爆出大量连接拿不到的异常,还伴随着无法获取数据库连接池的情况

2)Dubbo Consumer端有大量的Dubbo超时和重试的异常,且重试3次后,均失败。
3)Dubbo Consumer端的最大并发时91个

Dubbo Provider端的最大并发却是600个,而服务端配置的dubbo最大线程数即为600

这个时候,出于性能测试的警觉性,发现这两个并发数极为不妥。
按照正常的请求模式,DubboConsumer和DubboProvider展示出来的并发应该是一致的。此处为何会出现服务端的并发数被放大6倍,甚至有可能不止6倍,因为服务端的dubbo连接数限制就是600。
此处开始发挥性能测试各种大胆猜想:
1)是否是因为服务端再dubboServerHandle处理请求时,开启了多线程,而这块儿的多线程会累计到Dubbo的连接上,dragoon采集的这个数据可以真实的反应目前应用活动的线程对系统的压力情况;
2)压测环境不纯洁?我的小伙伴们在偷偷和我一起压测?(这个被我生生排除了,性能测试基本环境还是要保持独立性)
3)是否是因为超时所致?这里超时会重试3次,那么顺其自然的想,并发有可能最多会被放大到3倍,3*91=273<<600….还是不止3倍?
有了猜想,就得小心求证!
从RT的分布来看。基本上78.5%的响应时间是超过1s的。那么这个接口方法的dubbo超时时间是500ms,此时dubbo的重试机制会带来怎样的雪崩效应呢?

这里可以发现一个潜在的性能问题:
客 户端提交30个产品的查询请求,而服务端,则通过for循环和tair交互,所以这个接口在通常情况下的性能估计也得超过60-100ms。如果不是30 个产品,而是50或者100,那么这个接口的性能将会衰减的非常厉害!(这纯属性能测试的yy,当然这个暂时还不是我们本次关注的主要原因)
那么如此的架构,请求打在db上的可能性是比较小的, 由缓存命中率来保证。从线上真实的监控数据来看,tair的命中率在70%,应该说还不错,为什么在我们的压测场景,DB的压力确是如此凶残,甚至导致db的连接池无法获取呢?
所以性能验证场景就呼之欲出了:
场景:准备30个产品ID,保持不变,这样最多只会第一次会去访问DB,并将数据存入缓存,后面将会直接命中缓存,db就在后面喝喝茶好了!

Bug解决办法:
其实这过程中不仅仅有一些方法论,也有一些是性能测试经验的功底,更重要的是产出了一些通用性的性能问题解决方案,以及部分参数和技术方案的设计对系统架构的影响。
1)对于核心的服务中心,去除dubbo超时重试机制,并重新评估设置超时时间。
2)对于存在tair或者其他中间件缓存产品,对NULL数据进行缓存,防止出现缓存的变相击穿问题
GBA传承:
个人感受:
1)性能调优和诊断是一个不断挖掘的过程,不放过一个细节点,大胆猜想,小心求证
2)敢于质疑开发的建议和解决方案,提出自己的思路,并求证
3)勇于专研。性能调优就像追求自己心仪的女孩,有时努力了很久却没有任何结果,但是心动的感觉却是一生仅有的。
Dubbo超时机制导致的雪崩连接的更多相关文章
- dubbo超时重试和异常处理
dubbo超时重试和异常处理 dubbo超时重试和异常处理 参考: https://www.cnblogs.com/ASPNET2008/p/7292472.html https://www.tuic ...
- TCP/IP的三次握手和四次分手以及超时机制
使用INADDR_ANY的时候,往往针对多网卡情况,采用tcp连接方式,需要选择使用哪一个网卡发送,自己猜想应该是使用三次握手机制,如何判断目标地址不可达,应该使用的是超时机制,即握手超时则不可到达. ...
- Dubbo超时和重连机制
dubbo启动时默认有重试机制和超时机制.超时机制的规则是如果在一定的时间内,provider没有返回,则认为本次调用失败,重试机制在出现调用失败时,会再次调用.如果在配置的调用次数内都失败,则认为此 ...
- dubbo(九):timeout超时机制解析
在网络请求时,总会有各种异常情况出现,我们需要提前处理这种情况.在完善的rpc组件dubbo中,自然是不会少了这一层东西的.我们只需要通过一些简单的配置就可以达到超时限制的作用了. dubbo的设计理 ...
- 从报错“无效操作,连接被关闭”探究Transaction的Timeout超时机制
1.报错如下:Invalid Operation the connection is closed,无效操作,连接被关闭.这个错误是并不是每次都报,只有在复杂操作.大事务的情况下才偶然报出来. sta ...
- C# Socket连接请求超时机制
作者:RazanPaul 译者:Todd Wei 原文:http://www.codeproject.com/KB/IP/TimeOutSocket.aspx 介绍 您可能注意到了,.Net的Syst ...
- Dubbo超时重试机制带来的数据重复问题
Dubbo的超时重试机制为服务容错.服务稳定提供了比较好的框架支持,但是在一些比较特殊的网络环境下(网络传输慢,并发多)可能 由于服务响应慢,Dubbo自身的超时重试机制(服务端的处理时间超过了设定的 ...
- C# Socket.Connect连接请求超时机制
介绍 您可能注意到了,.Net的System.Net.Sockets.TcpClient和System.Net.Sockets.Socket都没有直接为Connect/BeginConnect提供超时 ...
- dubbo与trivial超时机制的深入思考
说在前面 trivial是根据之前设计的RPC框架而来的(还在增进当中),其中较为不同的一个点为,在客户端去掉了业务线程池,因为既然都要等待,不必要再加一层. 进入正题 有在网上看到这样的信息,“之前 ...
随机推荐
- 获取span中的值
js-code:var baseinfoallfeesum=$("#allFeeSum").html(); $("#baseInfoAllFeeSum").va ...
- javascript中判断变量时变量值为 0 的特殊情况
有时候我们在js中会直接判断变量是否存在值,下面列举一些情况: var a = 0; var b = 1; var c = ' '; var d; console.log( a ? 1 : null) ...
- 天猫首页迷思之-jquery实现整个div的懒加载(2)-插件面向对象化-闭包和原型的实例
前文有简单的实现了一个制作懒加载的方法,但其实以方法的形式做插件扩展性不强.那么本文就来用面向对象的方法将其制作成一个真正的插件: 我想要的最终的调用效果是: $(".loading&quo ...
- DockerFile的编写和注意的一些知识点
CMD,RUN,ENTRYPOINT之类的差别. VOLUMN和-V之间的差别. EXPOSE和-P的对应等. 今天上午写了一个脚本,可以传参数进IMAGE,让启动的CONTAINER具有不同的行为. ...
- java Socket启动服务
java -cp /Library/WebServer/Documents/Java/test/src com.zhidian.soft.sendOfClick localhost 8888 java ...
- python提纲
根据网上专栏整理提纲 1.模块介绍 2.time&datetime模块 3.random模块 4.os模块 5.sys模块 6.json&pickle模块 7.logging模块 8. ...
- (2)C# 创建ef oracle
1.NUGet下载 2.下载 Oracle Developer Tools for Visual Studio https://www.oracle.com/technetwork/develope ...
- 谜题27:变幻莫测的i值
与谜题26中的程序一样,下面的程序也包含了一个记录在终止前有多少次迭代的循环.与那个程序不同的是,这个程序使用的是左移操作符(<<).你的任务照旧是要指出这个程序将打印什么.当你阅读这个程 ...
- [Contest20171102]简单数据结构题
给一棵$n$个点的数,点权开始为$0$,有$q$次操作,每次操作选择一个点,把周围一圈点点权$+1$,在该操作后你需要输出当前周围一圈点点权的异或和. 由于输出量较大,设第$i$个询问输出为$ans_ ...
- 【贪心】Codeforces Round #402 (Div. 2) C. Dishonest Sellers
按照b[i]-a[i],对物品从大到小排序,如果这个值大于零,肯定要立刻购买,倘若小于0了,但是没买够K个的话,也得立刻购买. #include<cstdio> #include<a ...