一般常见的服务健康检查策略是连续多次服务状态测试成功或失败(如亚马逊或者阿里云均衡负载健康检查),服务健康状态才会发生迁移,具体来说就是如果当前服务健康,则必须连续测试失败 N 次,才认定为失败,如果中途出现成功则失败次数重置,反之亦然。
这种策略的好处是可以减少因网络偶然间抖动产生误判,缺点是需要花费更久时间才能判定服务状态,如果每次检查间隔为 X 秒,则至少需要 X * N 秒才能判定服务状态不健康。
在这里我们又遇到软件工程中常见的矛盾现象,一方面我们希望第一时间发现不健康的服务,另一方面我们又希望不要误判服务状态(比如服务刚刚恢复时健康检查成功,但服务随即崩溃...),这两点需求有着不可调和的矛盾,因此生产实践上通常允许动态配置参数N。
如果用伪代码描述该策略,则:
var 服务状态
var 测试成功计数器
var 测试失败计数器
const 连续失败次数阈值
const 连续成功次数阈值
while(true)
测试结果 = 执行测试();
如果 测试结果 == 失败
测试失败计数器++
如果 服务状态 == 失败
测试成功计数器 = 0
如果失败计数 > 连续失败次数阈值
服务状态 = 失败
否则什么也不做
否则(即测试结果 == 成功)
测试成功计数器++
如果服务状态 == 成功
测试失败计数器 = 0
如果成功计数 > 连续成功次数阈值
服务状态 = 成功
否则什么也不做
等待 X 秒
描述该策略对应的状态机示意图:
health-transition-machine.jpg
下面是一个应用以上伪代码的服务状态变化示例:
health-check-demo.jpeg
提请读者注意,该示例的失败和成功连续次数 N = 3,同时 Y轴 0 表示状态不健康或测试失败, 1 表示状态健康或测试成功。
服务状态先是由健康转移到不健康(3-4),然后又从不健康转移到健康(10-11),最终还是转移到不健康(18-19)。
可以看到尽管服务测试状态中途多次跳变,但由于次数未达到阈值,服务状态始终处于稳定状态。因此,该策略非常具有实用价值。
参考链接:
网友评论