thrift在大量链接断开时缺陷分析与解决
Posted 哥的私房菜
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了thrift在大量链接断开时缺陷分析与解决相关的知识,希望对你有一定的参考价值。
01 问题
有一个使用了thrift的后台服务,在链接在3W左右时,断开2000链接,导致其他链接断开,如下图:
在链接断开时,发现服务器有大量CLOSE_WAIT状态的链接
通过tcpdump抓发发现,受影响的链接是因为业务超时,从而client主动发送了close给server端
02 线上定位
使用nc创建500,511,512,1000,1024,1500,2000个链接,看是否能复现以上问题
通过以上测试,发现在断开512以下链接时,server端没有受影响,断开的越多,受影响越明显
03 分析
服务是否受影响与断开链接个数相关,查看服务器配置,发现对应服务配置的iothreadnum是8,对比统计群中其他未出故障的服务器,发现iothreadnum是32,那么,iothreadnum可能是导致问题的一个原因
通过tcpdump抓包发现,超时间时间小的业务最先受影响,所以,业务有可能是因为iothread太少,又受资源回收堵塞,导致业务超时,从而导致的一系列的故障
04 线下复现
使用ping接口向morpheus创建3W个链接,设置100ms超时,3s ping一下,10000qps,设置server端iothreadnum为1,8,32,64
另外创建500,511,512,1000,1024,1500,2000个ping链接,然后断开
断开1500个链接时,复现线上问题
05 小结
服务出现CLOSE_WAIT状态,应该是client主动发起了断开,
而且通过tcpdump抓包,也发现client在断开链接的时候,主动向server主动发起了close
iothreadnum越大,能承载的安全断开的链接数就越大,但是随着断开链接的数量越多,超时间越小,服务总是受影响
06 代码逻辑
此时通过代码看下thrift链接到底是一个什么样的逻辑
thrift中链接资源回收代码如下:
其中 setIdle和event_del功能一样,都是socket监控,setIdle同时能修改状态,所以删除event_dev
在分析代码,发现除returnConnection的操作应该都不会阻塞iothread,所以先将returnConnection注释掉,发现服务器除了没有回收资源,导致大量CLOSE_WAIT状态的链接外,没有影响其他业务的链接
07 改进(1)
将returnConnection操作独立到其他线程,缓慢(相对原来)进行资源回收,效果如下
以上方法确实能解决问题,但是真正的耗时出现在哪里呢?
08 改进(2)
对returnConnection中各行代码耗时进行统计
通过以上测试发现rease耗时较多,此时才算真相大白,因为vector的删除,会引起大量的资源copy,所以耗时最大
将vector修改为set耗时下降2个数量级,基本可以解决业务需求
09 问题
如果业务连接数很高(比如:3W以上),允许的超时时间足够小(比如:1ms以下),在出现大量链接断链的情况下,如何解决链接回收问题呢?
以上是关于thrift在大量链接断开时缺陷分析与解决的主要内容,如果未能解决你的问题,请参考以下文章