在分布式系统中经常使用心跳(Heartbeat)来检测Server的健康状况,但从理论上来说,心跳无法真正检测对方是否crash,主要困难在于无法真正区别对方是宕机还是“慢”。传统的检测方法是设定一个超时时间T,只要在T之内没有接收到对方的心跳包便认为对方宕机,方法简单粗暴,但使用广泛。
1. 传统错误检测存在的缺陷
如上所述,在传统方式下,目标主机会每间隔t秒发起心跳,而接收方采用超时时间T(t<T)来判断目标是否宕机,接收方首先要非常清楚目标的心跳规律(周期为t的间隔)才能正确设定一个超时时间T,而T的选择依赖当前网络状况、目标主机的处理能力等很多不确定因素,因此在实际中往往会通过测试或估计的方式为T赋一个上限值。上限值设置过大,会导致判断“迟缓”,但会增大判断的正确性;过小,会提高判断效率,但会增加误判的可能性。但下面几种场景不能使用传统检测方法:
1. Gossip通信
但在实际应用中,比如基于Gossip通信应用中,因为随机通信,两个Server之间并不存在有规律的心跳,因此很难找到一个适合的超时时间T,除非把T设置的非常大,但这样检测过程就会“迟缓”的无法忍受。
2. 网络负载动态变化
还有一种情况是,随着网路负载的加大,Server心跳的接收时间可能会大于上限值T;但当网络压力减少时,心跳接收时间又会小于T,如果用一成不变的T来反映心跳状况,则会造成判断”迟缓“或误判。
3. 心跳检测与结果的分离
并不是每个应用都只需要知道一个目标主机宕机与否的结果(true/false)