(转)混沌工程(Chaos Engineering)初识

混沌工程是在分布式系统上进行实验的学科,目的是建立对系统抵御生产环境中失控条件的能力以及信心。

一、概述

工程师团队最不愿碰到的便是大半夜被电话叫醒,开始紧张地查验问题,处理故障以及恢复服务。也许就是因为睡前的一个很小的变更,因某种未预料到的场景,引起蝴蝶效应,导致大面积的系统混乱、故障和服务中断,对客户的业务造成影响。特别是近几年,尽管有充分的监控告警和故障处理流程,这样的新闻在 IT 行业仍时有耳闻。问题的症结便在于,对投入生产的复杂系统有多少信心。监控告警和故障处理都是事后的响应与被动的应对,那有没有可能提前发现这些复杂系统的缺陷呢br>

图中展示了混沌工程从2010年演进发展的时间线:

2010年 Netflix 内部开发了 AWS 云上随机终止 EC2 实例的混沌实验工具:Chaos Monkey

2011年 Netflix release了其猴子军团工具集:Simian Army

2012年 Netflix 向 区开源由 Java 构建 Simian Army,其中包括 Chaos Monkey V1 版本

2014年 Netflix 开始正式公开招聘 Chaos Engineer

2014年 Netflix 提出了故障注入测试(FIT),利用微服务架构的特性,控制混沌实验的爆炸半径

2015年 Netflix release了 Chaos Kong ,模拟AWS区域(Region)中断的场景

2015年 Netflix 和 区正式提出混沌工程的指导思想 – Principles of Chaos Engineering

2016年 Kolton Andrus(前 Netflix 和 Amazon Chaos Engineer )创立了 Gremlin ,正式将混沌实验工具商用化

2017年 Netflix 开源 Chaos Monkey 由 Golang 重构的 V2 版本,必须集成 CD 工具 Spinnaker(持续发布平台)来使用

2017年 Netflix release了 ChAP (Chaos Automation Platform, 混沌实验自动平台),可视为应用故障注入测试(FIT)的加强版

2017年 由Netflix 前混沌工程师撰写的新书“混沌工程”在 上出版

2017年 Russell Miles 创立了 ChaosIQ 公司,并开源了 chaostoolkit 混沌实验框架

Netflix公司介绍

2. Chaos Monkey & Simian Army

Chaos Monkey 的原则:避免大多数失效的主要方式就是经常失效。失效一定会发生,并且无法避免。在大多数情况下,我们的应用设计要保证当服务的某个实例下线时仍能继续工作,但是在那些特殊的场景下,我们需要确保有人在值守,以便解决问题,并从问题中进行经验学习。基于这个想法,Chaos Monkey 仅会在工作时间内被使用,以保证工程师能发现警告信息,并作出适当的回应。

混沌工程实验像 Chaos Monkey 只是杀杀机器而已是错误的理解。回溯混沌工程发展的时间线,业界对混沌工程的理解是逐步深入的。Netflix 开发的 Chaos Monkey 成为了混沌工程的开端,但混沌工程不仅仅是 Chaos Monkey 这样一个随机终止 EC2 实例的实验工具。随后混沌工程师们发现,终止 EC2 实例只是其中一种实验场景。因此, Netflix 提出了 Simian Army 猴子军团工具集,除了 Chaos Monkey 外还包括:

Chaos Gorilla:Chaos Monkey的升级版,模拟整个Amazon Availability Zone的故障,以此验证在不影响用户,且无需人工干预的情况下,能够自动进行可用区的重新平衡。

Chaos Kong:Chaos Gorilla的升级版,模拟整个region(一个region由多个Amazon Availability Zone组成)的故障。

Latency Monkey:在RESTful服务的调用中引入人为的延时来模拟服务降级,测量上游服务是否会做出恰当响应。通过引入长时间延时,还可以模拟节点甚至整个服务不可用。

Conformity Monkey:查找不符合最佳实践的实例,并将其关闭。例如,如果某个实例不在自动伸缩组里,那么就该将其关闭,让服务所有者能重新让其正常启动。

Doctor Monkey:查找不健康实例的工具,除了运行在每个实例上的健康检查,还会监控外部健康信 ,一旦发现不健康实例就会将其移出服务组。(隔离出服务,并且给相关人员足够的纠错时间,最终再关闭。)

Janitor Monkey:查找不再需要的资源,将其回收,这能在一定程度上降低云资源的浪费。

Security Monkey:这是Conformity Monkey的一个扩展,检查系统的安全漏洞,同时也会保证SSL和DRM证书仍然有效。

10-18 Monkey:进行本地化及国际化的配置检查,确保不同地区、使用不同语言和字符集的用户能正常使用Netflix。

进一步分析发现, FIT 的执行过程也影响了整个系统的监控指标,即实验群体与其他非实验群体的统计指标混合不可分辨:无法确定实验的进行时间,无法评估其影响是否超过了系统本身的噪音。为了进一步的区分,则需要进行更多更大的实验,这将有可能给用户带来不必要的中断。因此需要对实验集群和非实验群集的流量配比进行精细控制,同时因应无人值守的实验要求,则引入微服务架构中的断路器,如其超出预定义的误差预算,自动结束实验。这就是为何 Netflix 提出了新的 ChAP 以加强故障注入测试。

综上所述,混沌工程的发展不是一蹴而就的, Chaos Monkey 是其开端,但 区对混沌工程的理解在逐步深入,从对基础设施的扰动( EC2 实例随机终止等),到利用应用 关控制爆炸半径,再到精细化流量配比以区分影响,直至引入断路器实现真正的无人值守。

混沌工程9年来的发展,由浅入深,由基础设施演进到应用架构,不是单单运维看看就好。今天,许多公司(包括Google、Amazon、Microsoft、Germlin Inc.、University of California、Github、Thoughtworks等)都使用某种形式的混沌工程实验,来提高现代架构的可靠性。

混沌工程也同样适用于传统行业,如大型金融机构、制造业和医疗机构。交易依赖复杂系统吗大型银行正在使用混沌工程来验证交易系统是否有足够的冗余。是否有人命悬一线美国,混沌工程在许多方面被当做模型应用在了临床试验系统中,从而形成了美国医疗验证的黄金标准。横跨金融、医疗、保险、火箭制造、农业机械、工具制造、再到数字巨头和创业公司,混沌工程正在成为复杂系统改进学科的立足点。

3. 混沌工程与传统测试之间的区别

混沌工程和传统测试(故障注入FIT、故障测试)在关注点和工具集上都有很大的重叠。譬如,在Netflix的很多混沌工程实验研究的对象都是基于故障注入来引入的。混沌工程和这些传统测试方法的主要区别在于:混沌工程是发现新信息的实践过程,而故障注入则是对一个特定的条件、变量的验证方法。

和故障注入类似,故障测试方法通过对预先设想到的可以破坏系统的点进行测试,但是并没能去探究上述这类更广阔领域里的、不可预知的、但很可能发生的事情。

在传统测试中,我们可以写一个断言(assertion),即我们给定一个特定的条件,产生一个特定的输出。测试一般来说只会产生二元的结果,验证一个结果是真还是假,从而判定测试是否通过。严格意义上来说,这个过程并不能让我们发掘出对于系统未知的、尚不明确的认知,它仅仅是对我们已知的系统属性可能的取值进行测验。而实验可以产生新的认知,而且通常还能开辟出一个更广袤的对复杂系统的认知空间。

混沌工程实验的可能性是无限的,根据不同的分布式系统架构和不同的核心业务价值,实验可以千变万化。下面是部分混沌实验的输入示例:

模拟整个云服务区域或整个数据中心故障;

跨多实例删除部分 Kafka 主题来重现生产环境中发生过的问题;

挑选一个时间段,和针对一部分流量,对其涉及的服务间调用注入一些特定的延时;

方法级别的混乱(运行时注入):让方法随机抛出各种异常;

在代码中插入一些指令可以允许在这些指令之前运行故障注入;

强制系统节点间的时间不同步;

在驱动程序中执行模拟 I/O 错误的程序;

让某个 Elasticsearch 集群 CPU 超负荷。

4. 实施混沌工程的先决条件

在引入混沌工程之前先要确定你的系统是否已经具备一些弹性来应对真实环境中的一些异常事件,像某个服务异常、 络闪断、瞬间延迟提高等。

混沌工程非常适合揭露生产系统中的未知缺陷,但如果确定混沌工程实验会导致系统出现严重的问题,那么运行这样的实验是没有任何意义的。你需要先解决这个缺陷,然后再引入混沌工程,然后你不仅能继续发现更多不知道的缺陷,还能提高对系统真实弹性水平(resilient)的信心。

引入混沌工程的另一个先决条件是监控系统,你需要用它来判断系统当前的各项状态。如果你没有对系统行为的可见能力,那么也就无法从实验中得出有效的结论。

二、混沌工程的五大原则

为了具体地解决分布式系统在规模上的不确定性,可以把混沌工程看作是为了揭示系统缺陷而进行的实验。破坏稳态的难度越大,我们对系统行为的信心就越强。如果发现了一个缺陷,那么我们就有了一个改进目标。避免在系统规模化之后问题被放大。

以下原则描述了应用混沌工程的理想方式,这些原则来实施实验过程,对这些原则的匹配程度能够增强我们在大规模分布式系统的信心。

1. 建立一个围绕稳定状态行为的假说(Build a Hypothesis around Steady State Behavior)

“稳定状态”是指系统正常运行时的状态。具体来说,系统的稳定状态可以通过一些指标来定义,当系统指标在测试完成后,无法快速恢复稳态要求,可以认为这个系统是不稳定的。

指标可以分为系统指标和业务指标。系统指标(如CPU 负载、内存使用情况、 络 I/O等)有助于帮助我们诊断性能问题,有时也能帮助我们发现功能缺陷。在混沌工程中,业务指标通常比系统指标更有用,因为它们更适合衡量用户体验或运营。业务指标通常回答这样的问题:

我们正在流失用户吗/p>

用户目前可以操作 站的关键功能吗如在电商 站里为订单付款,添加购物车等。

目前存在较高的延迟致使用户不能正常使用我们的服务吗/p>

Netflix使用客户点击视频流设备上播放按钮的速率作为指标,称为“视频每秒开始播放数(SPS)”,在文末会有相关介绍。

如果你还不能直接获取和业务直接相关的指标,可以暂时先利用一些系统指标,比如系统吞吐率,错误率,pct99延迟等。你选择的指标和业务关系越强,得到的可以采取可执行策略就越强。同样重要的是,在客户端验证服务产生的告警可以提高整体效率,而且可以作为对服务端指标的补充,以构成某一时刻用户体验的完整画面。

定义好指标并理解其稳定状态的行为之后,你就可以使用它们来建立对实验的假设。思考一下当你向系统注入不同类型的事件时,稳定状态行为会发生什么变化。例如,你向某个服务增加请求数,其稳定状态是被破坏还是保持不变果被破坏了,你所期待系统该如何表现/p>

我们的假设可以是实验措施不会使系统行为偏离稳定状态,比如:向我们的系统中注入的事件不会导致系统稳定状态发生明显的变化。

最后我们还需要思考一下这个问题:如何衡量稳定状态行为的变化。即便你已经建立了稳定状态行为模型,你也需要定义清楚,当偏离稳定状态行为发生时你要如何测量这个偏差。只有定义清楚“正常”的偏差范围,才可以获得一套验证假设的完善的测试集。

2. 多样化真实世界的事件 (Vary Real-world Events)

每个系统,从简单到复杂,只要运行时间足够长,都会受到不可预测的事件和条件的影响。例如负载的增加、硬件故障、软件缺陷、还有非法数据(有时称为脏数据)的引入。

我们无法穷举所有可能的事件或条件,但常见的有以下几类:

1.硬件故障;

2.功能缺陷;

3.状态转换异常(例如发送方和接收方的状态不一致);

4. 络延迟或隔离;

5.上行或下行输入的大幅波动以及重试风暴;

6.资源耗尽;

7.服务之间的不正常的或者预料之外的组合调用;

8.拜占庭故障;

9.资源竞争条件;

10.下游依赖故障。

也许最复杂的情况是上述事件的各类组合导致系统发生异常行为。

要彻底阻止对可用性的各种威胁是不可能的,但是我们可以尽可能减轻这些威胁。**在决定引入哪些事件时,我们应当估算这些事件发生的频率和影响范围,然后权衡引入他们的成本和复杂度。**我们不需要穷举所有可能对系统造成改变的事件,只需要注入那些频繁发生且影响重大的事件,同时要足够理解会被影响的故障域(故障的影响范围和隔离范围被称为故障的故障域)。

3. 在生产环境中运行实验 (Run Experiments in Production)

根据环境与流量模式的不同,系统运行效果亦将受到影响。由于运行效果可能随时改变,因此我们应将对实际流量进行采样作为获取可靠请求路径的惟一方法。为了保证系统运行方式的真实性以及同现有部署系统间的关联性,混沌工程原则强烈建议您直接面向生产流量进行实验。

即便你不能在生产环境中执行实验,你也要尽可能的在离生产环境最接近的环境中运行。越接近生产环境,对实验外部有效性的威胁就越少,对实验结果的信心就越足。

4. 持续自动化运行实验 (Automate Experiments to Run Continuously)

当今的系统越来越复杂,这意味着我们无法预先地知道生产环境的哪些变动会改变混沌工程实验的结果。基于这个原因,我们必须假设所有变动都会改变实验结果。在共享状态、缓存、动态配置管理、持续交付、自动伸缩、时间敏感的代码等等的作用之下,生产环境实际上处在一个无时不在变化的状态。

最开始执行混沌实验,可能就是手动执行,但是实验的手动运行工作属于劳动力密集型任务,因此难以长久持续。相反的,我们应该自己投入精力来开发混沌工程的工具和平台,以期不断降低创建新实验的门槛,并能够完全自动运行这些实验。

5. 最小化爆炸半径 (Minimize Blast Radius)

混沌实验通过很多方法来探寻故障会造成的未知的、不可预见的影响,关键在于如何让这些薄弱环节曝光出来而不会意外造成更大规模的故障。我们称之为最小化“爆炸半径”。

当我执行混沌实验时,一般先只作用于很少的用户之上,这样的风险也最小,他们不能代表全部生产流量,但他们是很好的早期指标。当自动化实验成功之后,就需要扩大实验范围:运行小规模的扩散实验,再进行小规模的集中实验,最后就是大规模无自定义路由的实验。扩大实验范围的目的是进一步暴露小范围实验无法发现的一些问题。

我们也会经常运行本来只会影响一小部分用户的测试,却由于级联故障无意中影响到了更多的用户。在这些情况下,我们不得不立即中断实验。虽然我们绝不想发生这种情况,但随时遏制和停止实验的能力是必备的,可以避免造成更大的危机。

为了让尽可能高效地应对实验发生不可预期的情况,我们要避免在高风险的时间段运行实验。例如我们只在所有人都在办公室工作的时间段运行实验。

三、混沌成熟度模型(Chaos Maturity Model)

标准化混沌工程定义的一个目的是,在执行混沌工程项目时,我们有标准来判断这个项目做得是好是坏,以及如何可以做得更好。混沌工程成熟度模型(CMM)给我们提供了一个评估当前混沌工程项目成熟度状态的工具。把你当前项目的状态放在这个图上,就可以据此设定想要达到的目标,也可以对比其他项目的状态。

可以基于实验成熟度等级的8个方面进行混沌实验可行性评估。

2. 混沌工程实验接纳度等级

接纳度用来衡量混沌工程实验覆盖的广度和深度。接纳度越高,暴露的脆弱点就越多,你对系统的信心也就越足。

混沌工程就是利用实验提前探知系统风险,通过架构优化和运维模式的改进来解决系统风险,真正实现上述韧性架构,降低企业损失,提高故障免疫力。

完整的混沌工程实验是一个持续性迭代的闭环体系,大致分为以下几个步骤:

确定初步的实验需求和实验对象;

通过实验可行性评估,确定实验范围;

设计合适的观测指标;

设计合适的实验场景和环境;

选择合适的实验工具和平台框架;

建立实验计划,和实验对象的干系人充分沟通,进而联合执行实验过程;

搜集预先设计好的实验指标;

待实验完成后,清理和恢复实验环境;

对实验结果进行分析;

追踪根源并解决问题;

将以上实验场景自动化,并入流水线,定期执行;之后,便可开始增加新的实验范围,持续迭代和有序改进。

1. 实验可行性评估

在前面的提及了混沌成熟度模型CMM,从熟练度和接纳度对实验技术的成熟度做了定下分析。此处的实验可行性评估,依照这个可行性评估模型,会针对具体的实验需求和实验对象进行细致评估。常见的一个形式是对照“可行性评估问题表”,对实验对象的干系人进行访谈。可行性评估问题表的内容会包含以下几个方面:

架构抵御故障的能力:通过对实验对象的架构高可用性的分析和评估,找出潜在的系统单点风险,确定合理的实验范围。

实验指标设计:评估目前实验对象判定业务正常运行所需的业务指标、应用健康状况指标和其他系统指标。

实验环境选择:选择实验对象可以应用的实验环境:开发、测试、预生产、生产。

实验工具使用:评估目前实验对象对实验工具的熟悉程度。

故障注入场景及爆炸半径:讨论和选择可行的故障注入场景,并评估每个场景的爆炸半径。

实验自动化能力:衡量目前实验对象的平台自动化实施能力。

环境恢复能力:根据选定的故障注入场景,评估实验对象对环境的清理和恢复能力。

实验结果整理:根据实验需求,讨论确定实验结果和解读分析 告的内容项。

2. 观测指标设计与对照

观测指标的设计是整个混沌工程实验成功与否的关键之一。在进行混沌工程实验过程中,系统可观测性已成为一种“强制性功能”,良好的系统可观测性会给混沌工程实验带来一个强有力的数据支撑,为后续的实验结果解读、问题追踪和最终解决提供了坚实的基础。

以下是常见混沌工程实验的观测指标类型:

业务性指标:价值最大,探测难度最大

应用健康指标:反映应用的健康状况

其他系统指标:较易获取,反映基础设施和系统的运行状况

指标对照是指将“观测指标”与“指标的稳定状态”进行对照。很多的用户还是无法定义一个合适的业务指标,如无法准确定义一个稳定状态,那么我们也可以退而求其次,使用多个指标进行联合分析来对照。

3. 实验场景和环境的设计

实验场景和环境的设计要努力遵循以下三大设计目标:

在生产环境运行实验

持续自动化运行实验

最小化实验场景的“爆炸半径”

实验场景(故障注入)设计

七、混沌工程案例

1. Netflix: SPS

某些组织有非常明确的,和收入直接相关的实时指标。例如像 Amazon 和 eBay 会跟踪销售量,Google 和 Facebook 会跟踪广告曝光次数。由于 Netflix 使用的是按月订阅模式,所以没有这类指标。Netflix也会测量注册率,这是一个重要的指标,但是只看注册率不能反映整体系统的健康状况。

Netflix真正想要的是一个可以反映当前活跃用户的满意状况的指标,因为满意的用户才有可能连续订阅。可以这么说,如果当前和系统做交互的用户是满意的,那么我们基本可以确定系统目前是健康的。

遗憾的是,Netflix目前还没找到一个直接、实时的可以反映用户满意度的指标。Netflix会监控客服电话的呼叫量,这或许是一个可以间接反映客户满意度的指标,但是从运营角度出发,我们需要更快、更细粒度的反馈。Netflix 有一个还不错的可以间接反映用户满意度的指标——播放按钮的点击率。Netflix管这个指标叫做视频每秒开始播放数,简称为 SPS(Starts per sencond)。

SPS 很容易测量,而且因为用户付费订阅服务的直接目的就是看视频,所以 SPS 应该和用户满意度密切相关。这个指标在美国东海岸下午 6 点会明显高于早上 6 点。Netflix就可以据此来定义系统的稳定状态了。

相比某个服务的 CPU 负载来说,Netflix 的可靠性工程师(SREs)更关注 SPS 的下降:SPS 下降会立刻向他们发送告警。CPU 负载的尖刺有时重要有时不重要,而像 SPS 这样的业务指标才是系统边界的表述。这才是需要关注并验证的地方,而不是那些像 CPU 负载类的内部指标。

在 Netflix,SPS 也不是一个和人体体温一样的稳定指标,它也随着时间波动。下图描绘的就是 SPS 随时间变化的波动情况,可以看出,它有一个稳定的模式。这是因为人们习惯于在晚餐时间看电视节目。因为 SPS 随时间的变化可以预期,所以我们就可以用一周前的 SPS 波动图作为稳定状态的模型。Netflix 的可靠性工程师们总是将过去一周的波动图放在当前的波动图之上,以发现差异。就像下图中当前的图线是红色,上一周的图线是黑色。

(转)混沌工程(Chaos Engineering)初识

2. 阿里巴巴ChaosBlade

2012 年阿里内部就上线了 EOS 项目,用于梳理分布式服务强弱依赖问题,同年进行了同城容灾的断 演练。15 年 实现异地多活,16 年内部推出故障演练平台 MonkeyKing,开始在线上环境实施混沌实验,然后 18 年输出了 ACP 专有云产品 和 AHAS 公有云产品,其中 AHAS 旨在将阿里的高可用架构经验以产品的形式对外输出,服务于外部。19 年推出 ChaosBlade 项目,将底层的故障注入能力对外开源,同年也推出混沌实验平台专有云版本 AHAS Chaos。

ChaosBlade 中文名混沌之刃,是一款混沌实验实施工具,支持丰富的实验场景,比如应用、容器、基础资源等。工具使用简单,扩展方便,其遵循 区提出的混沌实验模型。具体可以参考:阿里巴巴混沌测试工具ChaosBlade两万字解读。

声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2021年6月1日
下一篇 2021年6月1日

相关推荐