长连接为什么需要心跳

2021/5/25 10:29:30

本文主要是介绍长连接为什么需要心跳,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

首先,无论是自己设计的长连接还是websocket长连,都需要自己设计心跳机制来维持长连。从应用层协议来看,维持一个建立连接的必要条件似乎就是客户端和服务端均维持双方的连接信息,均用一个结构体来描述连接五元组(协议+源ip+源端口+目的ip+目的端口)。那么,是不是只要双方在应用层保证双方的连接信息不被清掉,就可以一直维护长连接呢。答案自然是否定的,长连接都是建立在TCP协议上的,所以我们先要了解操作系统是如何维护TCP协议连接状态的。

TCP 连接状态

所谓的TCP连接不是物理的连接,是为了实现数据的可靠传输由通信双方进行三次握手交互而建立的逻辑上的连接,通信双方都需要维护这样的连接状态信息。比如netstat经常看到连接的状态为ESTABLISHED,表示当前处于连接状态(这里需要注意的是这个ESTABLISHED的连接状态只是操作系统认为当前还处在连接状态)。可能链路已经不通,只是TCP层还没有感知到这一信息,操作系统层面显示的状态依然是连接状态,而且因为TCP层还认为连接是ESTABLISHED,所以作为应用层自然也就无法感知当前的链路不通。

TCP KeepAlive 机制

TCP协议实现中是有保活机制的,也就是TCP的KeepAlive机制(此机制并不是TCP协议规范中的内容,由操作系统去实现,如果操作系统不进行定期清除失活的连接,会导致网络性能下降,甚至会耗尽端口,理论上若TCP没有KeepAlive机制是不会断连的),KeepAlive机制开启后,在一定时间内(一般时间为2h),参数tcp_keepalive_time)在链路上没有数据传送的情况下,TCP层将发送相应的KeepAlive探针以确定连接可用性,探测失败后重试10(参数tcp_keepalive_probes)次,每次间隔时间75s(参数tcp_keepalive_intvl),所有探测失败后,才认为当前连接已经不可用。这些参数是系统级别,可以调整。

因此,按照TCP的KeepAlive机制,默认的参数,显然不能满足要求。那是不是调小点就可以了呢?调整参数,当然是有用的,但是首先参数的系统级别的,调整起来不太方便,更换机器还得记得调整参数,对系统的使用方来说,未免增加了维护成本,而且很可能忘记;其次由于KeepAlive的保活机制只在链路空闲的情况下才会起到作用,假如此时有数据发送,且物理链路已经不通,操作系统这边的链路状态还是ESTABLISHED,这时会发生什么?自然会走TCP重传机制,要知道默认的TCP超时重传,指数退避算法也是一个相当长的过程。因此,一个可靠的系统,长连接的保活肯定是要依赖应用层的心跳来保证的。

应用层维护心跳好处

应用层维护心跳的好处自然是能够及时发现链路故障问题,尽早地建立新的连接进行故障转移。

比如客户端每隔3s通过长连接通道发送一个心跳请求到服务端,连续失败5次就断开连接。这样算下来最长15s就能发现连接已经不可用,一旦连接不可用,可以重连,也可以做其他的failover处理,比如请求其他服务器。

比如某台服务器因为某些原因导致负载超高,CPU飙高,或者线程池打满等等,无法响应任何业务请求,如果使用TCP自身的机制无法发现任何问题,然而对客户端而言,这时的最好选择就是断连后重新连接其他服务器,而不是一直认为当前服务器是可用状态,向当前服务器发送一些必然会失败的请求。

 



这篇关于长连接为什么需要心跳的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程