乐趣区

如何正确实现heartbeat协议

一些思考

为什么要实现 heartbeat

为了确认链接, 通信 channel 是健康的, 为了尽快感知如下情况:

  • TCP FIN 包可能丢掉 / 没有发送
  • 网络设备可能出现故障
  • 应用出现故障

为什么要在应用层实现 heartbeat

即, 为什么不使用 tcp keepalive

tcp keepalive 无法检测应用的状态

TCP 的 KeepAlive, 在 a 开启对 b 的 keepalive 时, 可以验证: 在 a 的操作系统层面上, a to b 的链路是好的. 但无法检测应用层的状态. 如:

  • 逻辑错误, 如应用层死锁, 进程进入了无法预测的状态.
  • 负载过高无法服务.

等等.

tcp keepalive 没有应用层灵活

应用层可以做到逐个链接使用不同策略. 而 tcp keepalive 设置是对 os 的.

tcp keepalive 是否能穿透负载均衡器

个人觉得可以, keepalive 也是 tcp packet. 在 4 层负载均衡下显然是可以的. 这里会用阿里云 slb 做一下测试.
7 层很可能不行. 有待尝试.

单向 / 双向 heartbeat

双向 heartbeat 明显能检测出所有链路问题.
单向 heartbeat, 在如下前提下

  • heartbeat 发起端 (client) 在 heartbeat 多次失败情况下, 断开链接.
  • heartbeat 接收端 (server) 在多次 heartbeat 检测都未更新情况下, 断开链接.

也可快速检测出失效的 tcp 链接.
注意, 在 client 到 server 链路通, server 到 client 链路不通的情况下. 若 client 未对 heartbeat 结果做检测. 则 server 将一直收到 heartbeat, 导致 server 也不能快速检测到 tcp 链接问题.

实现要点

  • 心跳是对链接的
  • 失败多次检测验证
  • 有正常业务流量验证链路时, 不发送心跳包
  • 根据实际业务设计心跳策略, 如移动端要考虑尽可能减少电量, 流量消耗

Android 微信智能心跳方案

参考

Android 微信智能心跳方案

退出移动版