一些思考
为什么要实现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并没有透传keepalive packet.
单向/双向heartbeat
双向heartbeat明显能检测出所有链路问题.
单向heartbeat, 在如下前提下
- heartbeat发起端(client)在heartbeat多次失败情况下, 断开链接.
- heartbeat接收端(server)在多次heartbeat检测都未更新情况下, 断开链接.
也可快速检测出失效的tcp链接.
注意, 在client到server链路通, server到client链路不通的情况下. 若client未对heartbeat结果做检测. 则server将一直收到heartbeat, 导致server也不能快速检测到tcp链接问题. 若client行为不能控制(如, 手机APP, 可能有非官方客户端), 建议使用双向heartbeat.
实现要点
- 心跳是对链接的
- 失败多次检测验证
- 有正常业务流量验证链路时, 不发送心跳包
- 根据实际业务设计心跳策略, 如移动端要考虑尽可能减少电量, 流量消耗
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。