30

如何使用RST来解决TCP断开问题

 4 years ago
source link: http://mp.weixin.qq.com/s?__biz=MzU4ODgyMDI0Mg%3D%3D&%3Bmid=2247486997&%3Bidx=1&%3Bsn=2edb6d5a81baa73582deab06846cbf2f
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

女主宣言

最近在团队分享中,关于长链接的服务中,提到了一个TIMEWAIT的解决方案,具体关于TIMEWAIT具体产生的原因,原理,对系统产生的影响,会在其他的文章中给出具体的说明和解释,这个简单介绍一下概括性的内容。

PS:丰富的一线技术、多元化的表现形式,尽在“ 3 60云计算 ”,点关注哦!

简介

  1. 只有断开的发起端才会进入到TIME_WAIT的状态。

  2. TIME_WAIT状态的socket会占用系统的内存和CPU资源,占用的资源相对比较有限,比如内存每个也就是4K(没有具体测试,Net/3实现中,这三个的和位264字节,TCP/IP详解卷三中描述),整体在1万的情况下,也才40M的内存浪费,CPU是会有定期的轮询检查以及端口分配时的消耗,基本可以忽略。

综上所述,TIME_WAIT在一定的量级上时基本可以不用管的,尤其时笔者所在的长连接的场景,正常情况下就更难出现。如果想要做更好的优化,下面有两个思路,

  1. 通过加速TIME_WAIT的回收

  2. 通过RST的方式替代之前的FIN报文进行四次握手,实现一次就能断开释放掉资源。

本篇文章主要介绍通过RST的方式。

如何使用RST来解决TCP断开问题

Linger的原理介绍

Linger选项的定义了当socket中还有未发送的数据的情况下,执行了close的动作之后,后续会由什么样的表现。如果开启的Linger选项的情况,close会阻塞直到系统传输万所有的数据,或者到达指定超时时间,执行了close之后,再收到对端的消息的时候,会直接回复RST报文。

实现RST的方式就是通过开启Linger选项,并且超时时间设置为0,这样的话,就能直接丢弃掉没有发送的数据,发出RST报文。

golang版本的代码验证

客户端代码

服务端代码

通过客户端的代码中添加了如下代码

完成设置Linger选项的功能,关于需要转换相应的类型,是因为对应的方法是TCPConn而不是net.Conn的原因。

正常TCP关闭过程

执行结果的抓包数据如下所示

iQNRfab.jpg!web

通过报文可以看到,服务端在读取写入数据之后执行了正常的TCP四次挥手的关闭过程。

RST方式关闭过程

执行结果的抓包数据如下所示

UreU7fn.png!web

通过报文可以看到,服务端在读取写入数据之后直接发送RST的报文终止整个的连接过程。

通过以上的代码实现,以及抓包对报文的分析,可以看到通过Linger选项的设置,能够实现预期的通过RST的方式替代原有的FIN的关闭方式。对于Linger选项在各种实现方式下的不同表现,以及相应的限制,后续会持续的跟进。

RESET TCP and Linger

360云计算

由360云平台团队打造的技术分享公众号,内容涉及 数据库、大数据、微服务、容器、AIOps、IoT 等众多技术领域,通过夯实的技术积累和丰富的一线实战经验,为你带来最有料的技术分享

6jYzQzj.png!web


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK