很多人认为,TCP协议有KeepAlive机制,为何基于它的通讯链接仍然需要在应用层实现额外的心跳保活呢?本文将从移动端IM的角度告诉你,即使使用的是TCP协议,应用层的心跳保活仍旧必不可少。
在使用TCP长连接的IM服务设计中,往往都会涉及到心跳。心跳一般是指客户端每隔一定时间向服务端发送自定义指令,以判断双方是否存活,改喊因其按照一定间隔发送,类似于心跳,故称为心跳指令。
TCP是一个基于连接的协议,其连接状态是由一个状态机进行维护,连接完毕(三次握手)后,双方都会处于established状态,这之后的状态并不会主动进行变化。也就是说,即使上层不进行任何调用,一直使TCP连接空闲,那么它仍然是保持连接的状态。这个时候就需要一种机制来检测TCP连接的状态,KeepAlive就是背负这个使命出现的。
那么问题来了,KeepAlive是用来检测TCP连接状态的,那为什么还需要心跳呢?这里就需要考虑一种情况了,假如某台服务器因为某些原因导致负载超高,CPU100%,无法响应任何业务需求,但是使用TCP探针仍旧能够确定连接状态,这就是典型的连接活着但业务提供方已死的状态塌厅,对客户端而言,这时最好的选择就是断线后重新连接其他服务器,而不是一直认为当前服务器是可用状态,一直向当前服务器发送些必然后失败的请求。
从上面我们可以知道,KeepAlive并不适合检测双方存活的场景,这种场景还得依赖于应用层的心跳。应用层的心跳有着更大的灵活性,可以控制检测时机、间隔和处理流程,甚至可以在心跳包上附带额外信息。从这个角度而言,应用层的心跳的确是最佳实践。
TCP KeepAlive用于检测连接的死活,而心跳机制则附带一个额外团歼隐的功能:检测通讯双方的存活状态。
从上面我们可以得出结论,目前而言,应用层心跳的确是检测连接有效性,双方是否存活的最佳实践,那么剩下的问题就是怎么实现。
最简单粗暴的方法是定时心跳,如每隔30秒心跳一次,15秒内没有收到心跳包则认为当前连接已失效,断开连接并进行重连。这种做法最直接,实现也简单。唯一的问题就是耗电和耗流量。以一个协议包 5 个字节计算,一天收发 2880 个心跳包,一个月就是 5 x 2 x 2880 x 30 = 0.8 M 的流量,如果手机上多装几个 IM 软件,每个月光心跳就好几兆流量没了,更不用说频繁的心跳带来的电量损耗。
既然频繁心跳会带来耗电和耗流量的弊端,改进的方向自然就是减少心跳频率,但也不能过于影响连接检测的实时性。基于这个需求,一般可以将心跳间隔根据程序状态进行调整,当程序在后台时(这里主要指安卓),尽量拉长心跳间隔,5分钟、甚至10分钟都可以。
而当App在前台时则按照原来规则 *** 作。连接可靠性的判断也可以放宽,避免一次心跳超时就认为连接无效的情况,使用错误积累,只在心跳超时n次后才判定当前连接不可用。
通过 长时间保持双方连接 ,从而:
下面,我将对每种原因进行分析
当进程被杀死后,长连接也会随之断开
当移动客户端网络状态发生变化时(如移动网络 &Wifi切换、断开、重连),中橘亮也会使长连接断开
如网络状态差、 DHCP 的租期到期等等,都会使得长连接发生 偶然的断开
其实,说得简单点: 高效维持长连接的关键在于
整体概括如下:
这是本文的重点,下节开始会详细解析
对国、内外主流的移动 IM 产品( WhatsApp 、 Line 、微信)进行了心跳机制的简单分析 &对比,具体请看下图
下面,将根据市面上主流的心跳机制,设计 一套心跳机制方案
在下面的方案设计中,将针对这3个问题给出详细的解决方案。
为了减少流量 &提高发送效率,需要精简心跳包的设计
主要从心跳包的内容 &大小入手,设计原则具体如下
心跳包 = 1个 携带少量信息 & 大小在10字节内 的信息包
为了 防止 NAT 超时 &减少设备资源的消耗(网络流量、电量、CPU等等), 心跳发送的间隔时间 是 整个 心跳机制方案设计的重点。
心跳发送间隔时间的设计原则如下
下面,我将详细讲解 自适应心跳间隔时间 的设计方案
1.如何自适应计算心跳间隔 从而使得心跳间隔 接近 当前 NAT 超时时间?
注:只有当心跳间隔 接近 NAT 超时时间 时, 才能最大化平衡 长连接不中断 &设备资卖宽源消耗最低的问题 。
2.如何检测 当前网络环境的 NAT 超时时间 发生了变化 ?
注:在检测到 NAT 超时时间 发生变化后,重新自适应计算心跳间隔 从而使得心跳间隔 接近 NAT 超时伍兆时间
该机制的核心在于, 如何 判断长连接的有效性
在网上流传着一些用于判断长连接是否有效的方案,具体介绍如下
至此,关于心跳保活机制已经讲解完毕。
很多人认为, TCP 协议自身就有 KeepAlive 机制,为何基于它的通讯链接,仍需 在应用层实现额外的心跳保活机制 ?
先来看看 KeepAlive 机制 是什么
KeepAlive 的机制 不可 替代心跳机制 的具体原因如下:
KeepAlive 机制无法代替心跳机制, 需要在应用层 自己实现心跳机制以检测长连接的有效性,从而高效维持长连接
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)