如何提高微服务架构的可用性

  Netflix通过Peter Alvaro在论文 《路径驱动的故障注入(Lineage-driven fault injection)》 中提到了一套名为“Molly”的算法和自身的故障注入测试FIT(failure injection testing)实现了这套安全地自动化故障注入测试。Molly是从一套系统的无故障状态出发,然后试图去回答说“系统是如何达到目前这种无故障的状态的?”简单举例介绍一下这个算法的原理。先利用自身的追踪系统绘制一个树来表示每个请求经过的所有的微服务,假设如下图所示:

物联网

(A or R or P or B)

  在最开始,上图中的四个节点都是必须的,且正常的。然后从这个正确输出反推,随机选择一个节点注入故障,找到并构建支持其正确性的逻辑链条图 。当节点注入故障后,这时可能有三种情况:

  这个请求失败,我们已经找到一个节点会故障,从而我们可以删除未来的实验中包含这个故障。

  这个请示是成功的-但这个失败的节点不是关键性的

  这个请求成功,有高可用节点取代了这个失败

  在这个例子中,首先在Ratings中注入失败,但请求是成功的。说明Rating失败并不会影响服务的使用,那就先把这个节点排除,重新绘制请求树:

物联网

(A or P or B) and (A or P or B or R)

  这时可以看到,请求可以通过(A or P or B)的方式实现,也可以通过 (A or P or B or R)的方式实现。接下来再在Playlist中注入故障,这时请求还是成功的,因为请求转发到备用节点上执行,这里将会有一个新的节点可以访问。

物联网

(A or PF or B) and (A or P or B) and (A or P or B or R)

  这时可以更新公式,说明可以通过(A or PF or B) and (A or P or B) and (A or P or B or R)三种方式请求服务。然后通过这样不停的测试直到遍历完所有正确输出,没有失败的节点可以找到。

  Molly没有规定怎么搜索空间,所以实现时会估算所有的方案,然后随机选择最小的方案的集合。比如,最后的方案可能是[{A}, {PF}, {B}, {P,PF}, {R,A}, {R,B} …]。先选择所有的单节点注入失败,再选择所的有双节点的组合注入失败,依此类推。

  这个测试的目的是在影响大量成员前找到和修复故障,在生产环境上进行故障测试时,不能接受引起大量的问题节点。为了避免这个风险,只能在指定的范围构建测试,指定的范围包含两个关键的概念:故障范围(failure scope)和注入点(injection points)。故障范围指的是,把一次故障测试可能产生的影响,限制在一个可控的范围内,这个范围可以小到某个特定的用户或者设备,也可以大到所有用户的1%。而注入点指的是系统内计划会发生故障的组件,比如RPC层,缓存层,或者持久层。下图是这个测试的流程示意图:

物联网

 

  故障模拟测试从FIT服务把故障模拟元数据注入到Zuul(缘边网关服务)开始,如果请求符合故障范围(failure scope)则注入失败。这个故障可能是延迟服务调用,或达到持久层失败。每个被接触到的注入点(injection points)检查这个请求的上下文是否为指定要被注入故障的组件,如果是,在这个注入点模拟故障。