一些思考
为什么要实现 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 微信智能心跳方案