读书笔记:《混沌工程》第一部分——混沌工程介绍

Posted by Jiajie Wu on March 19, 2020

混沌工程是一门新兴学科,它的初衷是通过实验性的方法,让人们能够建立复杂分布式系统在生产中抵御突发事件能力的信心。

————混沌工程原则


生产环境中的分布式系统包含大量的交互、依赖点,这导致系统可能出错的地方非常多。每天,系统都可能面临各种问题,例如硬件故障、网络阻塞、流量激增……这些问题如果处理不好,就可能引发各种无法预料的异常(性能低下、业务异常……)。

混沌工程就是在系统基础设施上,通过实验的方式,主动找出系统中的脆弱环节。它为打造更弹性的系统提供帮助,也能帮助更透彻地理解系统的运行规律。

简单用例:
例如,在某个实例上运行“kill -9”指令,模拟某一服务的突然宕机;
例如,在生产环境中,选取具有代表性的一小部分流量。基于这部分流量,按照一定的规律自动运行一系列实验;

Tips——混沌工程与Netflix:

2008年,Netflix开始将服务迁移到云上,然后开始尝试咋生成环境中开展一些系统弹性测试。这个实践被称为混沌工程。最早诞生的“混沌猴子”以在生产环境中随机关闭服务节点而“臭名远扬”。“混沌金刚”由”混沌猴子”进化而来,因得益于“故障注入工具”(FIT)而规模扩大到非常大。

混沌工程并非简单地制造服务中断等故障,它存在的意义是让复杂系统中根深蒂固的混乱和不稳定性浮出水面,让我们可以更全面地理解系统中的固有现象,从而实现更好的系统设计,提升系统的弹性。

————《混沌工程》

第一章 为什么需要混沌工程

混沌工程通过设计和执行一系列实验,帮助发现系统中潜在的、可能导致灾难的、让用户受损的脆弱环节,推动工程师去主动解决这些问题。

它和某些大公司主流的被动式故障响应流程有着明显的区别 —— 主动性

混沌工程和测试的区别

混沌工程和故障注入、故障测试在侧重点和工具集的使用上有一些重叠。例如Netflix的很多混沌工程实验都是基于故障注入引入的。

我个人的理解,它们的区别主要在「已知」和「未知」,「被动」和「主动」,「单一」和「整体」,「结果确定」和「结果未知」。

故障注入和故障测试: 首先已知会发什么故障,然后将故障一个一个注入系统进行测试。在测试中,给定的条件会有对应的结果输出,这个输出一般都是二元结果(判定是通过/未通过)

混沌工程: 现实中,复杂系统可能发生的故障是无法全部列举出来的,因此要以探索的方式去发现这些隐藏的故障。有些情况无法定义其为“故障”,但也会影响系统的稳定性。例如流量激增、资源竞争条件、拜占庭故障(性能差或有异常节点发出错误响应、异常的行为、对调用者随机返回不同的响应)、非计划中的或消息内容非正常组合的处理等。

一些混沌工程实验的输入样例:

  • 模拟整个云服务器or整个数据中心的故障;
  • 跨多个实例删除Kafaka Topic来重现生产环境中发生过得问题;(Topic是对消息的归类方式,类似消息队列Queue)
  • 挑一个时间段,针对一部分流量,对它们涉及的服务之间调用注入一些特定延时;
  • 运行时注入:让方法随机抛出各种异常;
  • 代码插入:在目标程序中插入一些指令,使故障注入在指令执行前运行;
  • 强迫节点间时间不同步;
  • 在驱动程序中执行I/O错误
  • 让一个Elasticsearch集群的CPU超负荷
  • ……

实施的前提条件

1.系统已经具备一定的弹性来应对真实环境中的一些异常,例如某个服务的异常、网络闪断、瞬间延迟提高等。
2.拥有配套的监控系统,及时判断系统当前的各项指标状态。

混沌工程非常适合暴露系统中未知的脆弱环境,如果事先确定混动工程的实验会导致系统出现严重故障,那么进行这样的实验九没有意义。

在进行混沌工程的实验后,要么能继续发现系统更多的未知脆弱点,要么对系统的弹性水平更有自信。

混乱猴子(Chaos Monkey)

它会伪随机地关闭生产环境中正在运行的节点,而且关闭频率比正常故障的频率还要高。通过高频率地触发这些不常见的潜在灾难事件,使工程师更有动力在开发服务时考虑如何积极应对类似事件,工程师必须尽肯能、尽早地频繁处理这些故障。

目前,”混乱猴子”已经可以指定终止一组节点,并通过与 Spinnaker(Netflix的持续发布平台)集成来自动进行线上实验。

“混乱猴子”能尽可能地将服务节点失效带来的痛苦提前,同时让有所工程师在构建一个具有足够弹性应对失败的系统上,达成一个个一致的目标。

第二章 管理的复杂性

系统的优化通畅会从三个方面进行:性能、可用性、容错能力。

  • 性能:这里的性能特指使延迟或资源成本最小化。
  • 可用性:即系统正常响应和避免宕机的能力。
  • 容错能力:指系统从非正常状态中恢复的能力。

而在Netflix,还会考虑第四个方面——新功能开发的速度

综合考虑上面四点,Netflix采用了微服务架构。

复杂系统

本篇章提到,在微服务架构中,各个团队都是彼此独立地开发和运营他们的服务。这个架构以沟通协调为代价来提高新功能的开发速度。

微服务架构

上图是一个微服务系统架构,它由7个微服务组成。从微服务A到微服务G,每一个微服务都提供不同的功能,部分微服务存储某些信息。

假设一个用户通过手机APP访问该系统的一些信息:

  1. 请求首先进入微服务D(API服务);
  2. 微服务D本身并没有请求需要的所有信息,所以它进一步请求微服务C和微服务F,获取必要的数据;
  3. 微服务C和微服务F也需要更多的信息来满足需求,于是C请求A,F请求B和G;
  4. 接着也是相同的原因,A请求B,B请求E,G请求E。

对微服务D的一个请求扩散到整个微服务架构,而且在所有依赖服务返回响应或者超时之前,微服务D(API服务)都不会向手机APP返回响应信息。

微服务架构带来了开发速度和灵活性的提升,但也牺牲了对系统的掌控性和可理解性。这个缺失恰好为混沌工程提供了机会

  ps:混沌工程不需要知道系统内部具体是怎么实现的,它从整个系统出发,目的在于发现其中存在的未知潜在故障。

系统复杂性例子

在一个请求/响应的过长中,意大利面条式(形容逻辑纠缠、不清晰)的调用图代表了典型的、需要混沌工程关注的系统固有混乱。传统测试,如单元测试、功能测试、集成测试,在这里都是不够用的。传统测试只能告诉我们正在测试的系统中的某个属性的断言是真还是假。我们需要进一步发现更多会影响系统行为的未知属性。

————《混沌工程》第二章 P41


假设某系统环境存在以下特点:

  • 由于请求数量很大,采用一个固定的散列函数把用户均衡分开。例如微服务A背后数百个节点中,用户“CLR”的请求只会被路由到A42节点。如果A42出问题,系统会智能地把路由其他节点。
  • 当下游依赖服务出现异常,微服务A无法和持久层通信,它会从本地缓存中返回结果。
  • 每个微服务都会平衡考量监控、报警和资源。基于CPU负载和I/O性能决定在资源稀缺时加入节点,在资源空闲时去掉多余节点。

之后,基于这个假设的系统,书中介绍了一个被称为“牛鞭效应”的场景:

  1. 假设用户”CLR”的手机不在服务区内or网络出了问题,他启动APP,发送请求获取内容丰富的首页。这些请求都被缓存在手机和APP的请求队列中,等待网络恢复。
  2. 当网络突然恢复,数百个请求被一次性发出。微服务A收到了数百个请求,因为都来自用户“CLR”,所以请求都被路由到A42节点。这么大的流量下,A42无法使所有请求都从持久层获取数据,于是切换从本地缓存获取数据。
  3. 这一改变大大减少了为每个请求提供服务所需的处理时间和I/O开销,A42的CPU负载和I/O开销突然降低。依据上面的系统特点,系统进行了收缩,回收了A42节点,原属于A42的工作都被移到了A11节点上。
  4. 在请求转移过程中,对微服务A的请求超时,于是返回给了用户“CLR”不含个性化的内容。
  5. 用户“CLR”觉得奇怪而多刷新了几遍首页,这些请求路由到了A11节点。A11要处理的请求比平时多很多,也切换从本地缓存取数据,于是它的CPU负载和I/O开销也突然降低,被系统回收。
  6. 其他用户也陆续注意到首页显示的不正常,开始不断刷新内容,形成的超额流量致使微服务A中的节点不断被回收,系统一步步收缩。最终,整个集群系统都从缓存中获取数据,重试风暴压垮其余节点,微服务A掉线。
  7. 其他和微服务A有依赖关系的微服务,因为没有微服务A掉线的预案,进一步拉跨更多微服务,于是整个系统服务基本都中断了。

启发————

每一个单一微服务的行为都是合理的,但是在特定场景下,这些行为组合起来就会引发预料之外的灾难。输入中的任何一点扰动都会触发一个自我强化的循环,最终导致输出结果的剧烈波动。

架构师很难理解这些组件和组件知己恩的交互模式,并且从中预测出那些预料之外的系统效应。然而,混沌工程却提供了让这些效应浮出水面的工具。

混乱金刚(Chaos Kong) 混乱猴子的深入研究成果,相比混乱猴子,混乱金刚可以关闭整个AWS区域(多个数据中心)。

总结和后记

个人感觉无论是故障注入、故障测试,还是混沌工程,目的都是为了发现系统可能出现的故障,及时补救,提升系统的稳定性。区别只不过是前二者是对已知故障的排查,混沌工程是对未知、潜在故障的排查。故障注入和故障测试对系统进行第一层的稳定性提升,然后混沌工程在对系统进行第二层的稳定性提升,而这第二层是永无止境的,因为你永远不知道现在看似稳定的系统,在未来是否会发生什么始料未及的故障。

之后会继续阅读《混沌工程》后面的章节,深入了解混沌工程。

  ps:目前看到文中用到的例子都是微服务架构,可以猜测混沌工程在微服务架构中有着普遍且广泛的应用,就是不知道其他的架构又是怎么样的情况?需要调研了解下。

-END-