thrift在大量链接断开时缺陷分析与解决

Posted 哥的私房菜

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了thrift在大量链接断开时缺陷分析与解决相关的知识,希望对你有一定的参考价值。

01 问题

有一个使用了thrift的后台服务,在链接在3W左右时,断开2000链接,导致其他链接断开,如下图:

  1. 在链接断开时,发现服务器有大量CLOSE_WAIT状态的链接

  2. 通过tcpdump抓发发现,受影响的链接是因为业务超时,从而client主动发送了close给server端


02 线上定位

  1. 使用nc创建500,511,512,1000,1024,1500,2000个链接,看是否能复现以上问题

  2. 通过以上测试,发现在断开512以下链接时,server端没有受影响,断开的越多,受影响越明显


03 分析

  1. 服务是否受影响与断开链接个数相关,查看服务器配置,发现对应服务配置的iothreadnum是8,对比统计群中其他未出故障的服务器,发现iothreadnum是32,那么,iothreadnum可能是导致问题的一个原因

  2. 通过tcpdump抓包发现,超时间时间小的业务最先受影响,所以,业务有可能是因为iothread太少,又受资源回收堵塞,导致业务超时,从而导致的一系列的故障


04 线下复现

  1. 使用ping接口向morpheus创建3W个链接,设置100ms超时,3s ping一下,10000qps,设置server端iothreadnum为1,8,32,64

  2. 另外创建500,511,512,1000,1024,1500,2000个ping链接,然后断开

  3. 断开1500个链接时,复现线上问题


05 小结

  1. 服务出现CLOSE_WAIT状态,应该是client主动发起了断开,

  2. 而且通过tcpdump抓包,也发现client在断开链接的时候,主动向server主动发起了close

  3. iothreadnum越大,能承载的安全断开的链接数就越大,但是随着断开链接的数量越多,超时间越小,服务总是受影响


06 代码逻辑

此时通过代码看下thrift链接到底是一个什么样的逻辑

  1. thrift中链接资源回收代码如下:

    thrift在大量链接断开时缺陷分析与解决

  2. 其中 setIdle和event_del功能一样,都是socket监控,setIdle同时能修改状态,所以删除event_dev

    thrift在大量链接断开时缺陷分析与解决

  3. 在分析代码,发现除returnConnection的操作应该都不会阻塞iothread,所以先将returnConnection注释掉,发现服务器除了没有回收资源,导致大量CLOSE_WAIT状态的链接外,没有影响其他业务的链接


07 改进(1)

  1. 将returnConnection操作独立到其他线程,缓慢(相对原来)进行资源回收,效果如下

    thrift在大量链接断开时缺陷分析与解决

  2. 以上方法确实能解决问题,但是真正的耗时出现在哪里呢?


08 改进(2)

  1. 对returnConnection中各行代码耗时进行统计

  2. 通过以上测试发现rease耗时较多,此时才算真相大白,因为vector的删除,会引起大量的资源copy,所以耗时最大

  3. 将vector修改为set耗时下降2个数量级,基本可以解决业务需求


09 问题

  1. 如果业务连接数很高(比如:3W以上),允许的超时时间足够小(比如:1ms以下),在出现大量链接断链的情况下,如何解决链接回收问题呢?



以上是关于thrift在大量链接断开时缺陷分析与解决的主要内容,如果未能解决你的问题,请参考以下文章

《梦断代码》读书笔记

软件测试需求分析与跟踪

当 TCP 连接中的链接断开时的 send() 函数行为

软件测试需求分析与跟踪

罗昭锋 文献管理与信息分析一

一文带你了解 Thrift,一个可伸缩的跨语言 RPC 框架(pinpoint 源码分析系列)