TCP Keepalive机制与应用层心跳Heartbeat

TCP长连接中可能出现的问题

1.     很多防火墙路由器等对于空闲socket自动关闭

2.     对于非正常断开, 服务器并不能检测到. 为了回收资源, 必须提供一种检测机制.

于是,就有了心跳(HeartBeat)机制。


心跳机制的两种实现方案

目前而言,有两种方式实现TCP的保活(业内现状是IM方面几乎都采用第一种)

1.     应用层协议自己实现的心跳机制

很多应用层协议都有HeartBeat机制,由应用自己实现的应用层的心跳, 为心跳消息额外定义一个消息类型。通常是客户端每隔一小段时间向服务器发送一个数据包,通知服务器自己仍然在线,并传输一些可能必要的数据。使用心跳包的典型协议是IM,比如QQ/MSN/飞信等协议。

2.     TCP协议支持的心跳机制Keepalive

打开TCP协议已有的SO_KEEPALIVE选项. 一般实现在服务器侧,客户端被动响应前面一篇博客有具体介绍,这里就不多讲了。

 

TCP Keepalive和应用层HeartBeat优缺点

1.     TCP协议的Keepalive

优点:

系统内核完全替上层应用自动给做好了,内核层面计时器相比上层应用,更为高效

上层应用只需要处理数据收发、连接异常通知即可。

使用起来简单, 减少了应用层代码的复杂度. 也会更节省流量, 因为应用层的数据传输到TCP协议层时都会被加上额外的包头包尾. 由TCP协议提供的检活, 其发的探测包, 理论上实现的会更精妙, 耗费更少的流量.。

缺点:

第一点,keepAlive只能检测连接存活,而不能检测连接可用,比如某台服务器因为某些原因导致负载超高,CPU满了,无法响应任何业务请求,但是使用 TCP 探针则仍旧能够确定连接状态,这就是典型的连接活着但业务提供方已死的状态,对客户端而言,这时的最好选择就是断线后重新连接其他服务器,而不是一直认为当前服务器是可用状态,一直向当前服务器发送些必然会失败的请求;

第二点,如果tcp连接的另一端突然掉线,这个时候我们并不知道网络已经关闭。而此时,如果有发送数据失败,tcp会自动进行重传。重传包的优先级高于keepalive的包,那就意味着,我们的keepalive总是不能发送出去。 而此时,我们也并不知道该连接已经出错而中断。在较长时间的重传失败之后,我们才会知道。

2.     应用层HeartBeat

优点:

有着更大的灵活性,可以控制检测时机,间隔和处理流程,甚至可以在心跳包上附带额外信息,最重要的是可以做到没有上面所说的缺点,不光可以检测连接存在,还可以检测连接可用。

通用, 应用层的心跳不依赖协议. 如果有一天不用TCP要改为UDP了, 协议层不提供心跳机制了, 但是你应用层的心跳依旧是通用的, 可能只需要做少许改动就可以继续使用。

缺点:需要自己实现,增加开发工作量,由于应用特定的网络框架,还可能增加代码结构的复杂度,应用层心跳的流量消耗还是更大的,毕竟这本质上还是个普通的数据包。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章