关于TCP 半连接队列和全连接队列.docxVIP

  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  4. 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  5. 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  6. 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  7. 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
关于TCP 半连接队列和全连接队列 蛰剑 2021-06-24 最近遇到一个client端连接特别问题,然后定位分析并查阅各种材料文章,对TCP连接队列有个深化的理解 查材料过程中发觉没有文章把这两个队列以及怎样观看他们的目标说清楚,期望通过这篇文章能把他们说清楚一点 问题描述 JAVA的client和server,使用socket通信。server使用NIO。 1.间歇性的消灭client向server建立连接三次握手已经完成,但server的selector没有响应到这连接。 2.出问题的时间点,会同时有很多连接消灭这个问题。 3.selector没有销毁重建,一直用的都是一个。 4.程序刚启动的时候必会消灭一些,之后会间歇性消灭。 分析问题 正常TCP建连接三次握手过程: image.png 第一步:client 发送 syn 到server 发起握手; 其次步:server 收到 syn后回复syn+ack给client; 第三步:client 收到syn+ack后,回复server一个ack表示收到了server的syn+ack(此时client的56911端口的连接已经是established) 从问题的描述来看,有点像TCP建连接的时候全连接队列(accept队列)满了,尤其是症状2、4. 为了证明是这个缘由,马上通过 ss -s 去看队列的溢出统计数据: 667399 times the listen queue of a socket overflowed 反复看了几次之后发觉这个overflowed 一直在添加,那么可以明确的是server上全连接队列肯定溢出了 接着查看溢出后,OS怎样处理: # cat /proc/sys/net/ipv4/tcp_abort_on_overflow 0 tcp_abort_on_overflow 为0表示假如三次握手第三步的时候全连接队列满了那么server扔掉client 发过来的ack(在server端认为连接还没建立起来) 为了证明客户端应用代码的特别跟全连接队列满有关系,我先把tcp_abort_on_overflow修改成 1,1表示第三步的时候假如全连接队列满了,server发送一个reset包给client,表示废掉这个握手过程和这个连接(原来在server端这个连接就还没建立起来)。 接着测试然后在客户端特别中可以看到很多connection reset by peer的错误,到此证明客户端错误是这个缘由导致的。 于是开发同学翻看java 源代码发觉socket 默认的backlog(这个值把握全连接队列的大小,后面再详述)是50,于是改大重新跑,经过12个小时以上的压测,这个错误一次都没消灭过,同时 overflowed 也不再添加了。 到此问题处理,简约来说TCP三次握手后有个accept队列,进到这个队列才能从Listen变成accept,默认backlog 值是50,很简约就满了。满了之后握手第三步的时候server就忽视了client发过来的ack包(隔一段时间server重发握手其次步的syn+ack包给client),假如这个连接一直排不上队就特别了。 深化理解TCP握手过程中建连接的流程和队列 (图片来源:/something-about-phpfpm-s-backlog/) 如上图所示,这里有两个队列:syns queue(半连接队列);accept queue(全连接队列) 三次握手中,在第一步server收到client的syn后,把相关信息放到半连接队列中,同时回复syn+ack给client(其次步); 比如syn floods 攻击就是针对半连接队列的,攻击方不停地建连接,但是建连接的时候只做第一步,其次步中攻击方收到server的syn+ack后有意扔掉什么也不做,导致server上这个队列满其它正常恳求无法进来 第三步的时候server收到client的ack,假如这时全连接队列没满,那么从半连接队列拿出相关信息放入到全连接队列中,否则按tcp_abort_on_overflow指示的执行。 这时假如全连接队列满了并且tcp_abort_on_overflow是0的话,server过一段时间再次发送syn+ack给client(也就是重新走握手的其次步),假如client超时等待比较短,就很简约特别了。 在我们的os中retry 其次步的默认次数是2(centos默认是5次): net.ipv4.tcp_synack_retries = 2 假如TCP连接队列溢出,有哪些目标可以看呢? 上述处理过程有点绕,那么下次再消灭类似问题有什么更快更明确的手段来确认这个问题呢? netstat -s [root@se

文档评论(0)

bob157641554 + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档