混沌工程的陷阱_java

本文来自Nora Jones于2019年3月28日在第4届混沌工程大会上的分享,原文地址参考资料2。

Nora Jones 是《Chaos Enginering》一书的作者之一,曾在Netflix、Jet.com、Slack等公司实施和落地混沌工程,同时她也在Lund University攻读人因工程及系统安全专业的硕士学位,这也恰好给了她关于混沌工程结合人因相关的观点。

我花了几天时间去分析和理解这篇文章。原文是一篇ppt的讲稿,很多内容都是口语化的的表述,我在翻译的时候尽量将其转换成文章的形式来进行陈述。

混沌工程虽然不是一个太过新鲜的词汇,但是就目前国内而言,熟知的人也并不会太多。对于绝大多数人而言,有点超前,如果对于混沌工程不太了解,可以先看看我之前写的这篇《混沌工程初识篇》。

正文

首先我们以一个史上著名混沌实验做一个开场白——阿波罗1号。

阿波罗1号是美国阿波罗计划中的第一个载人飞行任务。当时计划将阿波罗1号的发射演习作为对阿波罗控制及服务模块的首次测试,并计划于1967年2月21日进行载人发射,而事实上并未成功。真实的情形是:在1967年1月27日发射演习测试期间,指挥舱中的一场大火烧死了全部在场的三名机组成员,于此同时,阿波罗1号的控制模块也被摧毁。3个月之后,阿波罗1号被NASA正式退役。

最终调查结果得出:舱内起火是由承载航天器动力的线路缺陷以及装有易燃和腐蚀性冷却剂的管道缺陷而引起的。起火之后,舱内内部压强较大,致使原本为了确保他们在飞行过程中安全的舱门无法打开,最终也就使得舱内机组人员并没有能够及时撤离。

当时,航天火箭并没有装载飞行燃料,参与人员错误地认为此项演习是相对安全的,即错误地认为“爆炸半径”(混沌工程的5项原则之一——最小化爆炸半径)能够得到有效地控制。因此,本应该具备的标准应急准备也没有实施,诸如消防、救援以及医疗小组也并没有到位。

这次事件的结局是悲惨的,同时也令NASA蒙羞。这无疑是一场失败的实验,我们在执行此类实验的时候应该保持高度的重视和警惕。这次事件之后,航天器的设计也被完全改变了。下面所要讲述的内容中也会多次提及阿波罗这个案例。

我们所从事的软件行业一般不会直接影响到人的生命安全,不过我们所服务的企业会从事一些商业活动,以此来获得盈利,而各式各样的事故会让企业承受不同程度的损失。事实上,这也就是为什么我们要在软件行业中践行混沌工程,并以此来构建我们对事故处理能力的信心的原因之一。

陷阱1、通过发现系统缺陷的数量来衡量混沌实验的成功与否

这是衡量混沌工程的ROI(投入产出比)的一个非常普遍的方式,很遗憾,这招用在混沌工程领域上并不怎么奏效。

援引 Dr. Robert L. Wears的一篇文章《The Error of Counting Errors》(链接见参考资料1), 其中就有这么一句话:You don't know much about safety simply by counting erros。在这句话中,我们可以简单的把“错误”这个词替换成“在混沌工程中发现的缺陷”,道理是一样的。仅仅是通过统计我们所负责的工具、产品或者团队自身中所发现的缺陷,是无法评判混沌工程是否成功的。

在《The Error of Counting Errors》(链接见参考资料1)这篇文章中还有这么一句话:Error counts are measures of ignorance, ranther than risk。直译为:错误数统计是用来衡量无知的,而不是用来衡量风险的。

“哇哦,混沌工程收获颇丰,仅上个季度我们团队就发现了200多个缺陷”。如果你们也正在推行混沌工程,也许你会发现领导层乐意把“发现更多的缺陷”作为OKR中的目标之一,我(Nora Jones)以前的团队就设定过类似的目标。我还和其它团队的同事讨论过这个目标,也对此有点踌躇,当时我那位同事说了这样一番话:你们是通过系统缺陷的数量来做评估的?如果你们在季度快要结束的时候还没有找到足够多的缺陷数量来完成OKR的话,我想我可以帮助你完成,我知道一个特别拽的Javascript项目。。(本文来自公众号:朱小厮的博客,ID: hiddenkafka)

统计系统缺陷的数量并不能真正地评估混沌工程项目的成功与否,反而还可能会引导你太过注重优化次优路径而导致错过混沌工程可以给你带来的其它正向收益。

混沌工程的陷阱_java_02

上图所示的是由 Darrell Huff 于1954年写的一本书,至今仍然很受欢迎。书中阐述了有关解释统计数据的错误,以及这些错误如何让我们产生了偏离实际的错误结论。推荐阅读。

混沌工程的目标不仅仅是简单地通过一些工具来发现系统缺陷,而是通过所找到的系统缺陷来引导我们走上弹性系统之路。

弹性是指系统的调节适应能力,它可以以此在面对各种变化和干扰时维持自身的关键功能。我这里所说的“系统”并不单指工具、服务等,还包括人,学会如何处理遇到的各类问题也是混沌工程的一部分。我们所处事的态度,以及在面对压力时的权衡抉择都会影响系统的运行行为。

让我们来架起混沌工程与弹性工程之间的桥梁,更多地讨论我们所进行的混沌实验的成功之处。并且我们也应该专注于学习那些我们所擅长的东西,而不仅仅是发现漏洞并指出系统风险。理解系统如何正确的运行会有助于我们更深入的找出和理解系统出问题的原因。

陷阱2、没必要系统相关的所有人都来参与实验的筹备和执行

让所有相关人员都到场,这一点执行起来确实比较困难。但是,如果团队里的所有成员能够坐在一起,然后一块探讨实验过程中系统潜在的变化,并且尽可能多表达关于系统的不同思考和想法,那么将会受益匪浅。

援引阿波罗1号的例子,这个陷阱二就存在了,当时认为没必要所有部门都参与这个演习测试,譬如急救和医疗援助队。

陷阱4、混沌工程应该是强制性的

(译者注:没有看错,这里就是陷阱4)

人为参与不可避免地会遇到种种协作问题,建立良好的人际关系也是混沌工程成功的一部分,我们需要去尝试理解别人在压力下如何权衡,以及如何发展专业知识和如何提炼专业知识等。

在混沌实验执行之后,强制要求相关人员把所找到的系统缺陷全部修复的行为,通常结局都不怎么好,反而还会损害与同事之间的关系。(译者注:混沌工程的推行者和混沌工程的受众并不隶属上下层关系,且后者更熟悉执行混沌实验系统的细节,发现的缺陷对于后者而言也有轻重缓急,应该尊重他们的意见和处理方式,而不是通过一种强制性的手段。)当我们像一个运维团队做事时候很容易陷入这样的一个陷阱。一味地追求发现更多的系统缺陷,并将这些缺陷添加到相关团队的代办事项中,且要求他们尽快完成这样的做法没什么太大的意义,也不会产生什么帮助。相反,你应该提供足够多的与系统缺陷有关的上下文信息,以便让此系统相关的负责人去更好地理解系统,以此权衡利弊类抉择去修复缺陷或者是忽略它而专注去做对业务更有利的事情。

于此同时,这里还有一个延伸的陷阱——应当把发现的系统缺陷都修复掉,而且最好是自动化修复的。我们需要明确的是:在使用混沌平台或者工具时的最佳实践是把系统缺陷的上下文信息提供给服务所有者,而不是自动执行修复程序或者消除系统缺陷。

陷阱5、在非生产环境中执行的实验不是真正的混沌实验

在生产环境中执行混沌实验或者自动化执行混沌实验之前,在非生产环境中执行混沌实验或者练习 GameDay 是非常有价值的、也是完全有必要的。

回想我在Netflix时,我们想要自动化混沌实验的配置和执行。但是,自动化配置混沌实验是一个很漫长的过程,我们不得不从多个不同的数据源收集大量的与服务配置有关的数据。当我们收集了所有的这些信息并进行了相关汇总之后,我们将其通过UI(被称之为 Monocle 的一个系统)的形式进行呈现,这样相关服务的负责人员可以从其中发现其潜藏的价值。Monocle的创建完全是一个意外,起初我们并没有想要创建它,我们只是想要实现自动化实验配置。这也验证了一个观点——与实际自动化实验相比,你可以在自动化实验过程中获得更多的价值。

陷阱6、执行实验是混沌工程中最重要的部分

创建和分享经验的过程才是践行混沌工程的最高收益。一旦我们能够通过 Monocle 发现系统缺陷并向服务的相关负责人展示时,那么我们从创建实验中获得的收益其实就已经超过了我们实际执行时所能获得的收益(其中一些我们甚至不需要运行,我们可能已经发现了存在的缺陷)。

实验执行前、实验执行时、实验执行之后所有的这些阶段都应平等和特定的关注。

由于篇幅关系,这里我只详细介绍一下在实验执行前的准备阶段的收益。

这里说一个有关 Consul 的故事。事故能够给我们提供一个这样的机会:让我们可以坐下来一起看看 A (Josie) 和 B (Javi) 在关于系统怎样运行的理解上有什么偏差。Josie,作为某个服务的负责人,觉得 Consul 的可用性可以达到100%, 即使出现问题,Consul 团队也会解决。同时,Javi 作为Consul 的架构师,认为用户不会做出这种可用性100%的假设。显然 Josie 和 Javi 从未明确对齐过关于 Consul 的各自预期,因为他们都假设对方应该知道这些认知。

Javi 拥有长期一线运维的经验,他觉得不会有用户会认为一个服务可以提供 100% 的可用性,而且在用 Consul 的时候也肯定会配置相关的重试策略。因此,他也从未把这一点写入文档里,也没有提示给用户有关假定可用性为100%的任何风险。Josie 非常喜欢 Consul,因为使用Consul可以方便快捷地存储和变更键值对,省时又省力,并且他也确实在很多地方都用上了 Consul。正常情况下,事情也确实如 Josie 所预期的那样,直到有一次发生了大规模停机。。。对于这次事故,显然有部分原因是因为各自预期的不匹配,且也缺乏交流相关内容的机会。不过话又说回来,除非真的遇到一次事故,否则类似的交流不会发生,因为大家不会因为一件彼此认为认知一致的事情而作任何交流。

这就是为什么要引入混沌工程原因。混沌工程就提供了一个机会——可以让我们去探索系统的缺陷,更重要的是,可以让我们一起交流各自关于系统运作的思考和认知。

混沌实验的设计者/组织者(理想情况下)应该是来自团队外部的人,他们需要引导并理解团队成员对于系统的可能的偏见。他们的任务是主持和引导团队内部人员进行对话、提问以及表达各自的观点,以期最终能够总结归纳出关于系统的假定。他们通过所寻求的团队中各个成员的反馈来构建后续的实验。(本文来自公众号:朱小厮的博客,ID: hiddenkafka)

尽管这个过程很费时间,但是非常重要(至少在混沌实验设计阶段)。团队中的各个成员需要发表各自对于系统的不同观点认知,最终能够整和出系统的一个假定。通常而言,这个假定不应该来自于实验的设计者/组织者。实验的设计者/组织者把大家聚到一起(30 - 60分钟),让每个成员有机会表达自己对系统的理解、当遇到某些故障时系统会发生什么。当来自不同团队的各自成员在一个屋子里一起参与实验的设计、一起讨论关于系统的期望时,你将会受益良多。提取你在这个阶段所获得的有效信息和接下来的实验执行同等重要。

搞清楚具体要做什么样的实验也是混沌工程的价值之一。

设计混沌实验的目标是让团队成员练习如何在问题的引导下讨论关于系统的不同认知,第二个目标是如何以结构化的方式设定实验策略。

陷阱7、晚点再担心(安全),最重要的是制造混沌

在阿波罗1号事故中,舱门原本是为了保证在飞行过程中宇航员的人身安全,但却由于内部压力无法打开而酿成惨剧。具有讽刺意味的是,原本旨在确保您安全的某些事情最终会导致灾难性的事故。Dr. Richard Cook 将这种类型的统称为“脆弱的防御措施(vulnerable defenses)”。

我们需要了解已采取的防御措施并测试其缺陷。通常,防御措施的缺陷很难被发现,而混动工程可以帮助你来揭示它。

制造混沌很容易,但是想要确保安全却很难。我们经常会犯错,总是在事情失败之后再想怎么去修复。陷阱7是一个很平常的陷阱,当我们还沉浸在成功制造混沌的喜悦中时,却不知可能已经身临险镜。

陷阱8、你可以在不了解系统的情况下进行混沌实验

在执行混沌实验之前,如果你不了解系统的相关信息如:轨迹、事件模型等,那么结局将会很惨。

陷阱3、践行混沌工程可以遵循特定的公式

为什么“陷阱3”会放在最后,这也是为了强调一下在践行混沌工程时并没有特定的万能公式可以遵循。在实施 Game Day 或者混沌实验时也没有特定的模板可用。

希望阅读此文的你可以跳出万能的公式,多从全局的角度去思考,多想想如何触达目标,而不是需要特定的“处方”。

总结

我们从混沌工程中学到的越多,我们对它的讨论也就越多,我们也就能越了解它。如果我们能够意识到这8个缺陷,那么我们可以更好地避开去更好的实践混沌工程。


混沌工程的陷阱_java_03


想知道更多?描下面的二维码关注我

混沌工程的陷阱_java_04

【混沌工程系列文章】