无论是飓风刮倒电线、火山灰云导致整个大陆的航班停飞,还是不起眼的啮齿动物咬断地下光纤——意外总会发生。我们无法阻止它发生,但我们可以做很多事情来为此做好准备。为此,谷歌每年都会举办一次公司范围内的、为期多天的灾难恢复测试活动——DiRT——其目的是确保谷歌的服务和内部业务运营在灾难发生后能够继续运行。
DiRT 的开发目的是通过有意造成关键系统和业务流程中的故障来发现漏洞,并在这些故障以不受控制的方式发生之前修复它们。DiRT 测试谷歌的技术稳健性(通过破坏实时系统)和运营弹性(通过明确阻止关键人员、领域专家和领导者参与)。在我们不具备弹性但应该具备弹性的地方,我们会尝试修复它。(请参阅边栏,“谷歌 DiRT:来自被测试者的视角”,作者:Tom Limoncelli。)
为了使 DiRT 式的活动取得成功,组织首先需要接受系统和流程故障作为一种学习手段。事情会出错。当它们发生时,重点需要放在修复错误上,而不是责备个人或团队的复杂系统故障。
组织还需要相信,从 DiRT 等事件中学习的价值证明了成本的合理性。这些活动并不便宜——它们需要大量的工程投入,伴随着对生产力的相当大的干扰,并可能导致面向用户的问题或收入损失。例如,DiRT 涉及数百名工程和运营人员数天的工作,而且事情并不总是按计划进行。DiRT 曾导致意外中断,在某些情况下还造成收入损失。然而,由于 DiRT 是一项公司范围内的演习,因此它具有让所有合适的人员随时待命的优势,以便在这些事件发生时能够控制住局面。
然而,为了最大限度地从这种恢复事件中获益,组织还需要投资于对其服务的持续测试。大型、DiRT 式的公司范围内的活动应该较少关注测试例行的故障情况,例如单服务故障转移或随叫随到的交接,而更多关注测试复杂场景或系统和团队之间较少测试的接口。复杂故障通常仅仅是系统中较小部分弱点的结果。随着系统较小组件不断得到测试,较大组件的故障变得不太可能发生。
一个简单的例子是测试组织从数据中心丢失中恢复的能力。这种丢失可以通过关闭设施电源或导致网络链路故障来模拟。理论上的响应将涉及一系列事件,从将流量从丢失的数据中心重定向到一系列特定顺序的单服务故障转移。然而,要扼杀恢复过程,只需要核心基础设施服务(例如 DNS(域名系统)或 LDAP(轻型目录访问协议))的单个实例发生故障转移失败。此类服务的故障转移测试可以而且应该持续进行,而不必等到 DiRT 事件发生。
启动此类演习的一个好方法是从小处着手,让演习逐步发展。从一开始就使其成为一项大型而复杂的事务很容易,但这样做可能会带来意想不到的开销和复杂性。
从小处着手不仅适用于参与演习的团队数量,也适用于测试的复杂性。一些易于记忆的规则和一个简单、可重复的演习形式对于快速吸引团队参与大有帮助。如果并非所有团队都认同,那么就与少数认同的团队合作,并且随着演习证明其自身有用,将会有更多团队参与。(奖励品也不会有害!)
谷歌的经验就是一个例子:最初形式的 DiRT 仅关注测试关键的面向用户的服务。最初的目标是所有主要的面向用户团队编写测试,并且测试是安全的,不会造成中断,尽管我们确实意识到某些测试不是很有用。这让团队“参与进来”。经过几次迭代,该演习吸引了更多的团队,并减少了低质量/低价值的测试。
测试设计也是如此。虽然测试的质量非常重要,并且直接影响演习的价值,但灾难恢复测试事件不必从过于复杂的测试或完美的一组测试(不存在)开始。DiRT 最初由各个小组测试特定于其服务的故障场景。总体的“灾难”仅仅是理论上的。在随后的 DiRT 演习中,测试的第一个重大中断是我们主要源代码管理服务器的中断,这暴露了几个依赖于此系统的未复制的关键功能。随着每个部分得到修复,我们逐步发展到涉及海湾地区重大“地震”的更大灾难。
我们通过关闭该地区的数据中心来模拟地震,该数据中心容纳了我们的许多内部系统。虽然中断暴露了几个单宿主服务,但也暴露了其他有趣的依赖关系。例如,为了避免受到中断的影响,一些团队决定将服务从数据中心故障转移到他们的工作站。由于“地震”发生在谷歌位于山景城的总部附近,测试团队也断开了山景城园区的连接——这意味着所有这些故障转移都失败了。此外,许多人没有预料到的是,数据中心中断导致身份验证系统以意想不到的方式发生故障,这反过来又将大多数团队锁定在他们的工作站之外。
当工程师们意识到快捷方式失败并且没有人可以完成任何工作时,他们同时认为现在是吃晚餐的好时机,最终我们对我们的自助餐厅进行了 DoS 攻击。为了与 DiRT 的目标保持一致,其中几个问题在下一次测试之前得到了修复。
如今,生产和内部系统、网络和数据中心运营以及包括人力资源、财务、安全和设施在内的多个业务部门都在 DiRT 期间进行测试。在最近的 DiRT 演习中,我们在没有通知的情况下关闭了多个数据中心集群、基础设施枢纽和办公室。大多数场景都得到了顺利解决。
非常重要的是要提到,远在谷歌甚至考虑 DiRT 概念之前,大多数运营团队已经在基于流行的角色扮演游戏的形式下持续测试他们的系统和交叉培训。随着问题的发现,修复被纳入设计过程。对于许多这些团队来说,DiRT 仅仅提供了一个安全的机会来测试风险更高的故障条件或与其他系统和团队之间较少测试的交互。
在为 DiRT 设计测试时,有几个角度需要考虑。最简单的情况,如前所述,是特定于服务的测试。此类别测试服务及其组件是否具有容错能力。这些测试通常是包含在内的,只需要直接团队响应,它们会发现技术和运营问题,包括文档空白、过时的配置或处理关键紧急情况的知识差距。理想情况下,这些测试会成为服务持续测试过程的一部分。
更复杂的技术测试用例会创建导致多个系统并行故障的场景。示例包括数据中心中断、光纤断裂或核心基础设施故障,这些故障表现在依赖服务中。如果设计这些测试的团队是跨职能的,并且包含来自公司各个领域的技术主管和主题专家,那么此类测试会更有价值。这些人了解其服务的复杂性,并且非常适合列举依赖关系和故障模式,以便设计出真实且有意义的场景。
此类测试的目标是识别服务和团队之间较少测试的接口中的弱点。此类场景可能具有潜在的风险和破坏性,并且可能需要多个团队的帮助才能解决错误情况。DiRT 是此类测试的绝佳平台,因为它旨在成为公司范围内的演习,并且所有解决问题所需的团队都可以按需提供。
经常被忽视的测试领域是业务流程和沟通。系统和流程高度交织在一起,将系统测试与业务流程测试分开是不现实的:业务系统的故障将影响业务流程,反之亦然,没有合适人员的工作系统也用处不大。
之前的“地震”场景暴露了几个这样的例子,其中一些在此处描述
海湾地区的丢失使山景城的人员和系统与世界其他地方断开连接。这意味着地理位置分散的办公室中的团队需要为关键运营提供全天候的随叫随到覆盖。然而,将警报和页面重定向到这些办公室所需的配置更改取决于受中断影响的系统。即使对于具有完全全球专业知识的团队,由于此流程故障,事情也没有顺利进行。
更成功的故障转移是内部业务功能的审批跟踪系统。然而,该系统本身毫无用处,因为所有关键审批人员都在山景城,因此无法使用。不幸的是,他们也是唯一有能力更改审批链的人。
在相同的场景中,我们测试了已记录的紧急通信计划的使用。第一次 DiRT 演习显示,在演习时,只有一个人能够找到该计划并出现在正确的电话桥接器上。在随后的演练中,超过 100 人能够找到它。这时我们了解到桥接器无法容纳超过 40 名呼叫者。在另一次通话中,其中一位呼叫者将桥接器置于保持状态。虽然保持音乐对灵魂来说很棒,但我们很快了解到我们需要从桥接器中踢出人员的方法。
作为另一个例子,我们模拟了数据中心长期停电。此测试挑战设施在备用发电机电力下运行较长时间,这反过来又需要在无法访问总部通常的审批链的情况下购买大量柴油燃料。我们期望设施中的某人调用我们记录的紧急支出流程,但由于他们不知道该流程在哪里,测试人员创造性地找到了一位员工,他自愿将全部六位数的费用记入他的个人信用卡。关于某事应该如何工作的详细文档并不意味着任何人都会使用它,或者如果他们使用它就会工作。确保这一点的唯一方法是通过测试。
当然,如果不对测试期间浮出水面的问题进行修复,那么测试几乎没有任何价值。拥抱失败作为一种学习手段的组织文化对于让团队例行地查找和解决其系统中的问题大有帮助。
DiRT 测试可能具有破坏性,并且应该预期在任何时候都会发生故障。可以采取几个步骤来最大限度地减少潜在的损害。
至少,所有测试都需要由跨职能技术团队进行彻底审查,并附带在出现问题时恢复的计划。如果以前从未尝试过该测试,则在沙箱中运行它可以帮助控制影响。然而,沙箱的另一方面是,这些环境的配置可能与生产环境中的配置显着不同,从而导致不太实际的结果。
有一些方法可以在不中断服务的情况下进行测试:在谷歌,我们“白名单”了我们已经知道无法在某些测试中幸存的服务。从本质上讲,它们已经未通过测试,并且在已知故障条件已为人所知的情况下,没有必要为它们造成中断。虽然服务可以“预先失败”并免除自身,但没有“预先通过”测试的概念——服务必须通过才能“通过”。
一个中央配备人员的指挥中心,了解并监控任何给定时间正在进行的所有测试,使 DiRT 成为更安全的测试环境。当意外发生时,指挥中心的团队(主要由各个领域的技术专家组成)会立即介入以恢复测试或修复违规问题。
DiRT 的核心是两个团队:技术团队和协调团队。
技术团队负责设计所有主要测试,并评估各个团队编写的所有测试的质量和影响。技术团队还负责实际造成较大的中断并监控它们,以确保事情不会出错。这也是处理测试意外副作用的团队。
协调员负责大部分测试的计划、安排和执行。他们与技术团队密切合作,以确保测试之间不会相互冲突,并且在 DiRT 之前完成每个测试的准备工作(例如设置沙箱)。
两个团队都充实了 DiRT 指挥中心。掌舵者通常是拥有足够大的电话簿的人。当没有太多事情发生时,指挥中心充满了干扰;它容纳了非常聪明的人,他们注意力持续时间短,睡眠不足且咖啡因过量。然而,当事情出错时——而且它们确实会出错——他们会保持警惕、目标明确,并全力以赴地进行灭火,并将错误传达、解决或回滚——此外,还会归档以进行修复。
指挥中心也是一个人的家,这个人拥有谷歌最有趣的 20% 项目之一:故事讲述者,他编造和叙述灾难,从僵尸袭击到以错误算命先生为主角的离奇心理惊悚片。
无论其形式如何,灾难恢复测试事件都是在受控环境中查找系统和流程问题的绝佳载体。基本原则是接受故障的发生,并且组织需要为此做好准备。通常,可靠的执行发起人和拥护者有助于为演习设定正确的基调。在谷歌的案例中,运营副总裁 Ben Treynor 一直倡导从持续测试中学习并抢先修复故障。
诚然,这些演习需要大量工作,但在不受控的环境中发生故障之前有机会识别和修复故障,这具有不可估量的价值。
喜欢还是讨厌?请告诉我们
Kripa Krishnan 是谷歌的技术项目经理,负责公司灾难恢复计划 (DiRT) 已有六年。她还领导 Google Apps for Government 工作,并且还曾在其他领域工作,包括存储和计费。她目前正在从事 Google Apps 的隐私和安全基础设施计划。在加入谷歌之前,Kripa 曾与科索沃远程医疗计划合作,在该地区建立远程医疗基础设施和虚拟教育网络。在之前的职业生涯中,她在印度经营一家剧院和表演艺术组织多年。
这是一个从负责运行被测试服务的工程师的角度看到的谷歌 DiRT(灾难恢复测试)演习的虚构描述。名称、地点和情况都已更改。
[电话铃响]
我 喂?
Mary 你好,Tom。我正在监督 DiRT 演习。你是 [服务名称] 的值班人员,对吗?
我 我是。
Mary 在这次演习中,我们假设 [服务名称] 数据库需要从备份中恢复。
我 好的。这是现场演习吗?
Mary 不,只是口头指导我完成即可。
我 嗯,我会按照我们的操作文档中的说明进行操作。
Mary 你能找到文档吗?
[几次按键点击之后]
我 是的,我找到了。
Mary 好的,启动一个服务的克隆,并将数据库恢复到其中。
在接下来的几分钟里,我发现了两个问题。首先,文档中的一个命令现在需要额外的参数。其次,用于执行恢复的临时区域没有足够的空间。编写该过程时,它有足够的空间,但此后数据库已增长。
Mary 提交了一个错误报告,要求更新文档。她还提交了一个错误报告,以建立一个流程来防止磁盘空间不足的情况发生。
我查看我的电子邮件,看到了来自我们的错误数据库的通知。这些错误抄送给了我,并被标记为 DiRT2011 的一部分。带有该标签的所有内容都将受到各方的关注,以确保在未来几个月内得到关注。在等待恢复完成时,我修复了第一个错误。
第二个错误将需要更多时间。我们需要将恢复区域添加到我们的季度资源估算和分配流程中。此外,我们将向我们的监控系统添加一些规则,以检测数据库大小是否接近恢复区域的大小。
我 好的,已读取服务的备份。我正在其上运行服务的克隆,并且我正在向您发送即时消息,其中包含您可以用来访问它的 URL。
[几次按键点击之后]
Mary 好的,我可以访问数据。看起来不错。恭喜!
我 谢谢!
Mary 好的,我让您继续工作。哦,我不应该告诉您这个,但在下午 2 点会有一些... 乐趣。
我 您知道我的值班时间在下午 3 点结束,对吧?如果您碰巧延迟一个小时...
Mary 没那么幸运。我在加利福尼亚,下午 3 点是您当地时间,那时我要去吃午饭了。
演习结束后一分钟,我收到一封电子邮件,其中包含指向演习后文档的链接。我使用发生的事情、指向已提交错误的链接等来更新它。我还想到了其他一些改进流程的方法,并在我们的错误数据库中为每个方法提交了功能请求。
下午 2 点,我的寻呼机没有响起,但我在我的仪表板上看到佐治亚州发生了中断。我们内部聊天室中的每个人都在谈论它。我不太担心。我们的服务在全球四个数据中心运行,系统已自动将 Web 请求重定向到其他三个位置。
过渡是完美无瑕的,仅丢失了“正在进行中”的查询,这完全在我们的 SLA(服务级别协议)范围内。
我的收件箱中出现了一封新电子邮件,解释说僵尸入侵了佐治亚州,并试图吃掉那里数据中心技术人员的大脑。僵尸切断了与数据中心的网络连接。没有网络流量进出。最后,电子邮件指出这是 DiRT 演习的一部分,没有实际的技术人员的大脑被吃掉,但网络连接确实已被禁用。
[再次,电话铃响]
Mary 嗨!玩得开心吗?
我 我总是玩得很开心。但我想您指的是佐治亚州中断?
Mary 是的。那些技术人员的遭遇真可惜。
我 嗯,我认识他们中的很多人,他们都有很大的大脑。那些僵尸
会吃好几个小时。
Mary 您的服务仍在 SLA 范围内吗?
我查看我的仪表板,看到在三个数据中心执行通常分布在四个位置的工作时,延迟略有增加,但仍在 SLA 范围内。事实是我不需要查看我的仪表板,因为如果延迟不可接受(或以如果放任不管会达到不可接受水平的速度增长),我会收到寻呼。
我 一切都很好。
Mary 太好了,因为我在这里监督另一个测试。
我 一群僵尸还不够吗?
Mary 在我看来还不够。您看,您的 SLA 说您的服务应该能够同时承受两个数据中心中断。
她是正确的。我们公司的标准是能够同时承受两次中断。原因很简单。数据中心和服务需要能够偶尔停机进行计划维护。在此窗口期内,另一个数据中心可能会因计划外原因(例如僵尸袭击)而停机。能够同时承受两次中断的能力称为 N+2 冗余。
我 那么您想让我做什么?
Mary 假设欧洲的数据中心因计划的预防性维护而停机。
我按照我们的程序临时关闭了欧洲的服务。来自我们欧洲客户的 Web 流量将自身分布在其余两个数据中心。由于这是一个有序的关闭,因此不会丢失任何查询。
我 完成了!
Mary 您在 SLA 范围内吗?
我查看仪表板,看到延迟进一步增加。整个服务都在两个较小的数据中心上运行。两个关闭的数据中心中的每一个都比组合的、较小的、工作的数据中心更大;然而,有足够的容量来处理这种情况。
我 我们勉强在 SLA 范围内。
Mary 恭喜。您通过了。您可以启动欧洲数据中心的服务。
无论如何,我决定提交一个错误。我们保持在 SLA 范围内,但这太接近极限了。当然我们可以做得更好。
我看了看我的时钟,看到快到下午 3 点了。我完成了填写演习后文档,就在下一个值班人员上线时。我向她发送了一条即时消息,解释她错过了什么。
我还提醒她锁好办公室的门。没人知道僵尸下一次会在哪里袭击。
Tom Limoncelli 是谷歌纽约办事处的站点可靠性工程师。
© 2012 1542-7730/12/0900 $10.00
最初发表于 Queue vol. 10, no. 9—
在 数字图书馆 中评论本文
Sanjay Sha - 企业应用程序的可靠性
企业可靠性是一门学科,它确保应用程序以一致、可预测且经济高效的方式交付所需的业务功能,而不会损害可用性、性能和可维护性等核心方面。本文介绍了一组企业可以应用的核心原则和工程方法,以帮助他们驾驭复杂的企业可靠性环境,并交付高度可靠且经济高效的应用程序。
Robert Guo - MongoDB 的 JavaScript Fuzzer
随着 MongoDB 随着时间的推移变得更加功能丰富和复杂,开发更复杂的方法来查找错误的需求也在增长。三年前,MongDB 将自研的 JavaScript fuzzer 添加到其工具包中,它现在是我们最多产的错误查找工具,负责在两个发布周期内检测到近 200 个错误。这些错误涵盖了从分片到存储引擎的各种 MongoDB 组件,症状范围从死锁到数据不一致。fuzzer 作为 CI(持续集成)系统的一部分运行,它经常捕获新提交代码中的错误。
Robert V. Binder, Bruno Legeard, Anne Kramer - 基于模型的测试:它处于什么位置?
您可能听说过 MBT(基于模型的测试),但与许多未使用 MBT 的软件工程专业人员一样,您可能对其他人使用这种测试设计方法的经验感到好奇。从 2014 年 6 月中旬到 2014 年 8 月初,我们进行了一项调查,以了解 MBT 用户如何看待其效率和有效性。2014 年 MBT 用户调查是 2012 年类似调查的后续调查,向所有评估或使用过任何 MBT 方法的人开放。它的 32 个问题包括 2013 年高级自动化测试用户会议上分发的一些调查问卷。一些问题侧重于 MBT 的效率和有效性,提供了管理者最感兴趣的数据。
Terry Coatta, Michael Donat, Jafar Husain - EA 的自动化 QA 测试:由事件驱动
对于数百万游戏爱好者来说,在 Electronic Arts 担任 QA(质量保证)测试员的职位似乎是一份梦寐以求的工作。但从公司的角度来看,与 QA 相关的开销可能看起来非常可怕,尤其是在大型多人在线游戏时代。