TCP保活(TCP keepalive) - 蚂蚁网-多维人生,三实而立!

TCP保活(TCP keepalive)

作者:易隐者 发布于:2012-10-15 11:30 Monday 分类:网络分析

TCP保活的缘起

       双方建立交互的连接,但是并不是一直存在数据交互,有些连接会在数据交互完毕后,主动释放连接,而有些不会,那么在长时间无数据交互的时间段内,交互双方都有可能出现掉电、死机、异常重启等各种意外,当这些意外发生之后,这些TCP连接并未来得及正常释放,那么,连接的另一方并不知道对端的情况,它会一直维护这个连接,长时间的积累会导致非常多的半打开连接,造成端系统资源的消耗和浪费,为了解决这个问题,在传输层可以利用TCP的保活报文来实现。

TCP保活的作用

1, 探测连接的对端是否存活
        在应用交互的过程中,可能存在以下几种情况:
(1), 客户端或服务器端意外断电、死机、崩溃、重启
(2), 中间网络已经中断,而客户端与服务器端并不知道
        利用保活探测功能,可以探知这种对端的意外情况,从而保证在意外发生时,可以释放半打开的TCP连接。

2, 防止中间设备因超时删除连接相关的连接表

       中间设备如防火墙等,会为经过它的数据报文建立相关的连接信息表,并为其设置一个超时时间的定时器,如果超出预定时间,某连接无任何报文交互的话,中间设备会将该连接信息从表中删除,在删除后,再有应用报文过来时,中间设备将丢弃该报文,从而导致应用出现异常,这个交互的过程大致如下图所示:

点击查看原图

       这种情况在有防火墙的应用环境下非常常见,这会给某些长时间无数据交互但是又要长时间维持连接的应用(如数据库)带来很大的影响,为了解决这个问题,应用本身或TCP可以通过保活报文来维持中间设备中该连接的信息,(也可以在中间设备上开启长连接属性或调高连接表的释放时间来解决,但是,这个影响可能较大,有机会再针对这个做详细的描述,在此不多说)。

常见应用故障场景:

       某财务应用,在客户端需要填写大量的表单数据,在客户端与服务器端建立TCP连接后,客户端终端使用者将花费几分钟甚至几十分钟填写表单相关信息,终端使用者终于填好表单所需信息后,点击“提交”按钮,结果,这个时候由于中间设备早已经将这个TCP连接从连接表中删除了,其将直接丢弃这个报文或者给客户端发送RST报文,应用故障产生,这将导致客户端终端使用者所有的工作将需要重新来过,给使用者带来极大的不便和损失。

TCP保活报文格式:

1, TCP keepalive probe报文

       我们看到,TCP保活探测报文是将之前TCP报文的序列号减1,并设置1个字节,内容为“00”的应用层数据,如下图所示:

点击查看原图

发送keepalive probe报文之前的TCP报文

点击查看原图

 TCP keepalive probe报文


2, TCP keepalive ACK报文

        TCP保活探测确认报文就是对保活探测报文的确认, 其报文格式如下:

点击查看原图

TCP keepalive ACK报文

TCP保活报文交互过程

        TCP保活的交互过程大致如下图所示:

点击查看原图


TCP保活可能带来的问题

1, 中间设备因大量保活连接,导致其连接表满

       网关设备由于保活问题,导致其连接表满,无法新建连接(XX局网闸故障案例)或性能下降严重
2, 正常连接被释放

       当连接一端在发送保活探测报文时,中间网络正好由于各种异常(如链路中断、中间设备重启等)而无法将该保活探测报文正确转发至对端时,可能会导致探测的一方释放本来正常的连接,但是这种可能情况发生的概率较小,另外,一般也可以增加保活探测报文发生的次数来减小这种情况发生的概率和影响。

TCP保活的设置

        一般而言,保活探测主要在服务器端实现,如果应用层有相应的保活机制时,传输层的TCP保活就可以不用。

        在windows系统中,我们可以通过修改注册表等来达到开启、调整保活相关
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters
KeepAliveInterval
项:Tcpip\Parameters
数值类型:REG_DWORD - 时间(以毫秒为单位)
有效范围:1 - 0xFFFFFFFF
默认值:1000(1 秒)
说明:此参数确定在收到响应之前,保活重传之间的时间间隔。一旦收到一个响应,将由 KeepAliveTime 值重新控制在下一次保活传输之前的延迟。如果经过 TcpMaxDataRetransmissions 指定的重新传输次数后仍无响应,将放弃连接。
KeepAliveTime
项:Tcpip\Parameters
数值类型:REG_DWORD - 时间(以毫秒为单位)
有效范围:1 - 0xFFFFFFFF
默认值:7,200,000(两个小时)
说明:此参数控制 TCP 试图通过发送保活数据包来验证空闲连接是否仍然保持的次数。如果远程系统仍然可以连接并且正在运行,它就会响应保活传输。默认情况下不发送保活数据包。应用程序可以在连接上启用此功能。

       关于Linux、HP UNIX、IBM AIX、SUN solaris等系统keepalive参数的设置和修改,请大家自行百度谷歌,在此我就不做简单搬砖的事情了。

标签: 防火墙 保活 keepalive 连接表 TCP保活 TCP keepalive


您对本文的评分:
当前平均分: 9.5(59 次打分)

版权所有:《蚂蚁网-多维人生,三实而立!》 => 《TCP保活(TCP keepalive)
本文地址:http://www.vants.org/?post=162
除非注明,文章均为 《蚂蚁网-多维人生,三实而立!》 原创,欢迎转载!转载请注明本文地址,谢谢。

评论:

羽风蓝
2017-08-31 15:17
我看到截图上保活报文的序列号是1833,那么理论上客户端此时的确认号也应该是1833吧,保活报文的长度是1,客户端的响应报文确认号还是1833,确认号不是应该+1么,还是tcp协议有判断是保活探测报文ack就不增加的机制么?
菜菜
2017-04-17 10:30
你好,有个问题,对方在收到保活报文时候需要响应一个ack,这个没错,但是这个响应的ack没有携带数据,为什么也消耗了一个seq(序号),这句话(TCP保活探测确认报文就是对保活探测报文的确认, 其报文格式如下:)下面的图,
易隐者
2017-04-17 15:42
@菜菜:保活报文中存在len=1的字段,保活响应报文就是对这个长度为1字节的字段的确认
abc
2012-12-23 23:06
1.这种TCP保活报文是不是只会出现在TCP的长连接中?
2.一个带有保活特性的业务应用,如果长期没有业务数据交互的话会一直保持连接的建立吗?
易隐者
2012-12-24 09:35
@abc:1,TCP保活跟长连接时两个不同的概念;
2,在启用TCP保活的情况下,应用一旦建立TCP连接,则该TCP连接在无业务数据交互的情况下会通过TCP保活报文一直维持这个TCP连接;
myapple
2012-10-25 01:59
借用学习啊
易隐者
2012-10-25 10:01
@myapple:感谢支持,欢迎经常关注,大家一起讨论学习。

发表评论:

Powered by 易隐者 基于emlog 皖ICP备12002343号-1