心跳检测以及应用层心跳包机制设计

博主联系方式:
QQ:1540984562
微信:wxid_nz49532kbh9u22
QQ交流群:892023501(嵌入式方向)
QQ交流群:856398158(后端方向)

心跳检测应用场景

心跳检测一般有两个作用:保活和检测死连接。

死连接情况

服务器与客户端不在一个网络中,之间的数据会经过多个路由器和交换机,如果其中某个必经之路的机器出现了故障,并且在一段时间内没有恢复,则会导致这之间的链路不再通畅,此时服务器和客户端之间没有数据交换。并且由于TCP连接是状态机,所以对于这种情况,通信两方是无法感知与对方的连接是否正常。又如果客户端因为网络原因或者崩溃等许多原因断开了与服务端的连接,然而服务端却不知道客户端已经断开了连接并等待客户端给他发送数据占用着系统资源,我们称这样的情况为“死连接”。
在这个情况中,我们只要在服务端向客户端发送一个数据包,即可检测连接是否正常,这类数据包称为心跳包,这种操作称为心跳检测。如果一个连接长时间没有正常数据来往,有没有心跳包来往,就可以认为这个连接已经不存在了,此时应该关闭socket来回收连接资源。

保活

一个客户端在连接服务器之后,如果长时间没有和服务器有数据来往,可能会被防火墙程序关闭连接,但是有时我们希望这个连接保持下去。因为对于即时通信来说,服务器没有消息时,确实不会有数据交换,但是连接关闭的话,新消息到来的话就无法接受到了。这种情况,我们只需要向对方发送心跳包即可实现保活。

传递有效业务数据

实际应用中,有时需要定时或者不定时地从服务端更新一些数据,可以把这类数据放在心跳包中,定时或者不定时更新。
但是对于连接数较多时,为了减轻网络带宽和流量,设计心跳包数据格式时应该尽量减少心跳包大小。

心跳包机制设计

通用心跳包设计

心跳包其实就是一个预先设置好格式的数据包,在程序中启动一个定时器定时发送即可。
但是如果通信两端有频繁的业务数据来往,此时这些数据包本身就可以起到保活的作用,就没有必要浪费流量发送心跳包了。
最佳的做法就是记录最近一次收发数据包的时间,在每次收数据和发送数据的时候就更新这个时间。而心跳检测的计时器在每次检测时都将这个时间与当前的系统时间做比较,如果时间间隔大于允许的最大间隔,则发送一次心跳包。
简而言之:在与对端之间没有数据来往达到一定时间间隔时,才发送一次心跳包。
同时检测心跳包的一方,应该是在与对端没有数据来往达到一定时间间隔时才做一次心跳检测。
一般来说是客户端主动向服务端发送心跳包,服务端做心跳检测来决定是否断开连接。从客户端的角度来说,客户端为了让自己得到服务端的正常服务,有必要主动和服务端保持正常连接。服务端在收到客户端的心跳包时,应该给客户端一个心跳应答。

有代理的心跳包设计

在后端服务程序与客户端之间存在代理服务时,后端服务与代理服务之间是长连接,代理服务与客户端之间也是长连接。
后端服务器的业务类型是订阅类型,客户端一旦订阅某个类型的主题,就很少或者不再发送数据给服务器了,服务器会将被订阅的数据下发到代理服务器,然后客户端从代理服务器获取数据。
在这里插入图片描述
现在有一个情况:客户端和代理服务之间的连接断开,代理服务和后端服务的连接正常。此时后端服务的下行数据会一直畅通,但此时客户端与代理服务可能已经断开好一会儿了。此时后端服务会根据下行数据更新最后一次心跳时间,所以会导致心跳检测误判后端程序与客户端的连接状态。因为这里我们使用的方法仍然是检测后端服务更新心跳包时间。
此时只需要更改机制为:只通过后端服务的上行数据来更新时间戳,若超过某段时间后仍然没有上行数据,则说明客户端已经断开了(这段时间内,服务端既没有收到客户端的业务数据包,也没有收到客户端的心跳数据包)

おすすめ

転載: blog.csdn.net/qq_42604176/article/details/121332484
おすすめ