故障检测是高可用系统中的一个重要内容,它是系统高可用的基础,只有故障能够被及时准确的检测出来,才谈得上高可用。心跳检测是常用的检测方法,它被广泛 地使用于各种系统,虽然心跳检测有很高的适用范围,但是它有很大的局限性,包括滞后性以及其他因素的影响,比如CPU忙或者网络阻塞的因素。
其实我们知道,心跳的目的只是想知道故障的结果,而不需要知道故障的原因和现象,但是故障的发生并没有这么简单。打个比方,当OUT OF MEMORY发生之前,一定会有内存不断被分配却极少释放的现象,导致最后可用内存不断减少,而最终发生这个错误。很多故障的发生实际上是一个渐变的过 程,我们可以监控这个过程来避免最终结果的发生,或者及时采取合适的措施。但也有不少故障的发生是突发的,没有任何预兆。当这些故障发生之前我们是无法预 测的,但是故障发生之后就会有相应的现象。比如网络故障,当这个故障发生时,任何在网络中传输数据的企图都会失败。因此,在心跳之前,仍然有足够的信息表 明网络发生了异常。
我们在上面主要论证除了心跳之外,有更多的手段来检测故障的存在,主要是根据各种状态来判断,就像中医诊断病情一样。假设存在A/B两台机器,他们之间的 网络状况可以有各种协议,比如ICMP/SNMP等。他们内部进程之间的也可以存在发送和接收数据时返回的错误信息能够表明网络状态和对方进程的状态。基 于状态反馈的故障检测理论认为,任何故障的发生之前或者发生之后存在与之相关的状态,能够甄别这个故障即将发生、可能发生或者曾经发生。
状态的传播主要还是要以推送为主。首先由关注的节点向服务器注册,然后由服务器将状态推送给各个节点。当然,也可以采用轮询的方式。如果节点数比较多的 话,可以采用级联的方式,这样,得到状态推送的节点可以级数增长。毕竟推送的时间很短,即使多级级联,时间消耗也只是t*n。
在进程中得到状态信息的代码位置可能在函数调用栈很深的地方,也可能出现在进程任意位置,但发送状态信息的目的地可能出现在另外一个进程。所以发现状态的代码本身并不能得到服务器的帮助,只能根据自身的设计进行处理,关键是故障的状态发现。