心跳机制

心跳(HeartBeat)


在计算机领域中,有很多概念和机制的命名,都参考了现实生活中已有的事物或者概念,两者之间一般都具有共同或者相似的行为。

例如:

  • 容器
  • 迭代器/游标
  • 父类、子类
  • 神经网络
  • 心跳

为何需要心跳机制


  • C/S架构的软件,采用长连接时,通常并不会一直都会有数据传输的。连接处于空闲状态的时间占有相当比例。如果客户端发生崩溃、断网等异常情况时,除非在此连接上继续发送数据产生错误返回,否则服务器无法得知客户端真的出现异常情况了。想要及时得知这一情况并做相应处理的话,就需要心跳机制。
  • 另一方面,app经常需要和服务器及时同步一些数据,也可以通过心跳包发送过去。

TCP内置的KeepAlive保活机制


  • 7,200,000 ms:TCP默认的心跳间隔时间是2个小时!,这在绝大多数APP中是无法忍受的。
  • 这就要提出另外一个问题:心跳间隔时间的不合理设置,可能会因为短暂的网络波动而断开健康的TCP连接。

实践中的疑虑


参与开发中的一个项目,心跳的间隔时间是8秒。检测到玩家断线时,客户端会有断线重连的提示。

现在遇到这样的bug:

流程如下:

玩家点击某个按钮 => 发送消息至服务器 => 服务器处理后,返回消息给客户端 => 客户端做出对应的UI表现

玩家反馈:

点击按钮没有任何反应,没有断线重连提示,服务器日志没有查到这位玩家发送的消息日志。

我猜想:

玩家在点击按钮的时候,正好网络波动网络消息没有发出去,他没有看见断线重连的提示,是因为:短暂之后(8秒之内)网络又好了。也就是说恰好网络波动只是出现在两次心跳之间,而没有被客户端检测到。所以玩家觉得网络没有任何问题(依据是客户端的断线重连提示),服务器日志却又查不到发送网络消息的日志。