为什么TCP的 KeepAlive 不能满足心跳需求?
首先说下心跳包的主要作用是告知对方连接端,我还活着,心还在跳。
前言:
的确,tcp 也有心跳机制,也可以让连接保活,那么我们为什么在socket层还要做一层心跳呢?事实上,TCP 的 KeepAlive 机制其实并不适用于此。tcp 的 Keep Alive 开启后,TCP 层每隔 7200 s 定时发送 KeepAlive 探针以确定连接可用性。一般时间为,失败后重试 10 次,每次超时时间 75 s。显然默认值无法满足我们的需求,但是你可能会说,我们把心跳间隔改短一点不就行了吗? 答案是不对的。
在某些极端情况,例如CPU 超载负荷,达到了100%,无法响应任何业务,但是TCP 的探针仍然可用,这样就会引起: TCP的探针探测是服务器可用的,但是实际可任务服务已死;这就是为什么不能用TCP心跳的原因;
另外,我们使用socket 心跳,而不使用tcp心跳另外一个原因就是:socket是基于业务层的,可以在心跳包做业务扩展,而tcp显然不合适;
NAT 超时时间:
下面解释一个概念 NAT , 是网络运营商维护的一个表,存储连接的时间。当这个连接的时间超过一定时间没有心跳时,运营商会把连接移除;
大部分移动无线网络运营商都在链路一段时间没有数据通讯时,会淘汰 NAT 表中的对应项,造成链路中断。
长连接心跳间隔必须要小于NAT超时时间(aging-time),如果超过aging-time不做心跳,TCP长连接链路就会中断,Server就无法发送Push给手机;(解决办法:心跳包失败回调里进行重连)
国内移动无线网络运营商在链路上一段时间内没有数据通讯后, 会淘汰NAT表中的对应项, 造成链路中断.
所以,如上所述,如果NAT超时,连接被运营商移除,连接就会中断,而实际上, 根据网上的一些说法, 中移动2/3G下, NAT超时时间为5分钟, 中国电信3G则大于28分钟, 理想的情况下, 客户端应当以略小于NAT超时时间的间隔来发送心跳包.
网友评论