韧性工程的重要性
本周 AWS 发生了更大的中断,当然媒体报道再次大肆报道。例如,“亚马逊网络服务中断使企业陷入困境”,华盛顿邮报的标题,仅举一个例子。
你可以找到更多的媒体报道。然而,对我来说,有趣的部分并不是 AWS 发生了罕见的中断之一。这是大多数文章的底线:AWS 发生了部分中断,因此使用 AWS 的公司步履蹒跚。
换句话说:AWS 是有罪的。这些公司是受害者。
个人觉得,没那么简单。实际上,我认为 AWS 按承诺交付,并且确信像 Netflix 这样的一些公司根本不会因为这次中断而步履蹒跚。那么,其他公司做错了什么?
不了解分布式系统
IMO 的第一个问题是,步履蹒跚的公司对分布式系统的本质了解得不够好,无法正确评估风险。
有趣的是,我刚刚在上一篇文章中描述了分布式系统的影响:
- 跨流程边界出现问题。
- 你无法预测什么时候会出错。
- 它会在应用程序级别打击你。
这就是您对分布式系统的基本总结。或者正如亚马逊首席技术官 Werner Vogels 有时描述的那样:
“一切都失败了,一直都是。” ——维尔纳·沃格尔斯
他之所以这么说,是因为 AWS 的人会做的很马虎。看看他们运营的系统环境的复杂性和规模以及他们经历的罕见的更大中断,他们做得非常好 . 他这么说是因为他真正了解分布式系统的本质。
这种“事情会出错并在应用程序级别打击你”不仅对应用程序的某些部分有效。您还需要考虑您使用的基础设施。在任何分布式系统中,即不同的进程(通常在不同的机器上运行)交互时,您必须查看所有“移动”部分及其交互。
您使用的基础架构也是分布式应用程序环境的一部分。这是陷入困境的公司没有(足够)考虑到的。
100% 可用性陷阱
如果软件工程师设计一个分布式应用程序,例如,使用微服务,至少有时他们会考虑他们自己实现的应用程序部分的潜在故障。
但是,一旦涉及应用程序与之交互的其他部分,无论是其他应用程序还是基础设施组件,100% 可用性陷阱就会发生。这个陷阱是一种普遍的、隐含的思维模式,在企业环境中尤其常见。陷阱是这样的:
100% 可用性陷阱(谬误)
我的应用程序与之交互的所有东西都是 100% 可用的。
如果您明确询问人们是否认为这些其他部分可能会失败,他们会说是的。但他们的决定和设计并没有以任何方式反映它。
想想你知道的应用程序代码,例如,尝试写入数据库。如果访问失败会怎样?是否有替代操作编码在这种情况下要做什么,例如,首先重试写入,如果仍然失败将写入请求放入队列并稍后处理,包括监视和处理队列的逻辑?
我很确定,没有这样的代码。最有可能的是,相应的异常被捕获、记录,然后……好吧,继续前进,就好像什么都没发生一样。在韧性工程中,这被称为“静默失败”。您检测到错误,决定忽略它并继续前进。
这种行为在某些地方可能很好,但通常情况并非如此。大多数情况下,这只是 100% 可用性陷阱的结果:从未讨论过故障场景,期望的行为仍未定义,因此实现开发人员不知道如何处理这种情况。因此,他们记录了出现问题并继续前进。他们还应该做什么?
不过,从业务角度来看,这通常不是您想要的。假设这是关于写命令。订单就是你赚钱的东西。订单就是你赖以生存的东西。因此,这是整个应用程序中最重要的一次写入。
现在假设如果由于某种原因写入失败,则命令只是默默地不写入。如果你搜索它,你可以在日志中找到它,但就是这样。这不是你想要的。
或者客户收到一条通用消息,例如:“处理您的请求时出现问题。请稍后再试。” – 这有点好,但也不是你想要的。
从业务的角度来看,您想要的根本不是失去任何订单,因为订单是您存在的基础。
因此,您会期望一些逻辑,例如首先重试写入。如果失败,将订单缓存在队列或其他辅助存储介质中,向客户发送消息,例如“非常感谢您的订单。由于暂时的技术问题,我们无法立即处理您的订单。但我们会在问题解决后尽快处理。这是一个 URL,您可以在其中跟踪您的订单处理状态”,实现并运行队列处理器以及订单处理状态页面。
如果您从业务角度对订单写入过程的期望行为进行推理,您可能会得到这样的结果。但由于 100% 可用性陷阱,通常不会进行这种讨论。
因 AWS 中断而步履蹒跚的公司很可能从未进行过这样的讨论。
不评估 SLA
但是,即使公司对分布式系统了解得不够好并陷入 100% 可用性陷阱,仍然存在 AWS 提供的 SLA,应将其视为风险管理来源。
阅读 AWS 提供的 SLA,我的第一个想法是,如果我想将停机风险降到最低,我需要自己采取额外的措施。我的印象是,步履蹒跚的公司没有这样的想法。
事件的事后分析表明,Kinesis 处于停电的中心。这也影响了其他一些使用 Kinesis 的 AWS 服务。
通常,像 AWS 这样的公司会尽量减少级联故障的可能性。但是在像 AWS 这样的复杂系统环境中,您往往会有微妙的、未知的交叉依赖关系,只有在发生重大故障时才会意识到这些依赖关系,即使您在分布式系统设计方面与 AWS 一样有经验。
但让我们暂时只关注 Kinesis。Kinesis 提供的 SLA 规定:
AWS 将尽商业上合理的努力使每个 AWS 区域在任何月度计费周期内的每个包含服务 4 的月正常运行时间百分比至少达到 99.9%(“服务承诺”)。
请注意该句子中的“商业上合理”。这不是不惜一切代价保持的保证,但前提是它在商业上对 AWS 有意义。如果他们不能遵守 SLA 的承诺,他们会提供补偿:
如果包含的服务不符合服务承诺,您将有资格获得如下所述的服务积分。
下表列出了根据计费周期内包含服务的实际可用性而定的补偿金额:
Monthly Uptime Percentage | Service Credit Percentage |
Less than 99.9% but equal to or greater than 99.0% | 10% |
Less than 99.0% but equal to or greater than 95.0% | 25% |
Less than 95.0% | 100% |
IMO 这是一个大胆的承诺。我不知道有任何 IT 部门为其本地基础设施提供甚至接近的 SLA——而且本地基础设施的复杂性比 AWS 提供的基础设施要简单几个数量级。因此,从我的角度来看,关于 SLA 没有什么可抱怨的。
但是,这就是重点:它不是 100% 的可用性保证。
一个月内 99.9% 的可用性意味着您每月仍有超过 43 分钟的不可用时间。这意味着您每月可以轻松丢失 10.000 条消息,而 AWS 不会违反其 99.9% 的可用性承诺。
如果 Kinesis 在一个月内停机最多 7.2 小时,您将少付 10% 的 Kinesis 账单,而对于每月最多 1.5 天的停机时间,您将少付 25%。仅当相关月份的停机时间超过 1.5 天时,您才无需支付任何费用。关于最近的 AWS 中断,这意味着受影响的公司可能会在下个月的 Kinesis 账单中获得 10% 或 25% 的信用额度。
请注意,这不包括因停电造成的收入损失或其他问题的补偿。
再说一遍:我认为 Kinesis SLA 非常好。但是,如果您将此 SLA 与 100% 可用性保证混淆并押注于持续正常运行时间,那么您就错了。
这只是关于使用 Kinesis。任何重要的基于云的应用程序都使用多种服务,通常是十几个或更多。如果您浏览他们的 SLA,您将获得类似的可用性承诺 。
现在让我们假设,您使用 10 个服务。为简单起见,让我们另外假设使用的所有服务都提供与 Kinesis 相同(良好)的 SLA。
重点是:使用的所有部件的可用性成倍增加!
这意味着:如果您使用 10 项具有 99.9% 可用性承诺的服务,那么总体而言,您使用的组合服务的可用性承诺将下降到 99%——如果它们完全不相关 . 如果它们具有依赖关系(正如我们在整个中断),预期可用性较低。这意味着如果所有服务都遵守其 99.9% 的可用性承诺,则在一个月内至少有 7.2 小时的可预期不可用性。
换句话说:如果没有额外的措施,您需要为平均云应用程序每月的一个工作日(从 9 到 5 个)不可用的基础设施做好准备。如果从这个角度来看,停电并没有什么特别之处。无论如何,这只是您需要期待的事情。这个故事令人惊讶的部分是这样的中断很少发生。
也许 AWS 做得太好了,通常远远超出了他们的承诺,结果客户认为可用性是理所当然的,如果预期发生,就会变得草率并抱怨很多。媒体也加入进来。
但最后,步履蹒跚的公司很可能没有足够仔细地评估 SLA。都在里面。你只需要做数学。
本地环境中的相同模式
总而言之,似乎步履蹒跚的公司
- 不了解分布式系统的效果不够好
- 陷入 100% 可用性陷阱
- 没有足够仔细地评估提供的 SLA。
但公平地说:这种心态和由此产生的行为不仅限于公共云的使用。我们随处可见。
我们在本地场景中看到的更多,其中数据库、消息队列、事件总线、容器调度程序、VM 管理程序等都被视为 100% 可用 - 但事实并非如此。此外,在设计在此基础架构上运行的应用程序之前,他们的 SLA(通常比我们看到的 Kinesis SLA 更差)通常没有得到足够仔细的评估。
此外,通常认为远程应用程序在本地环境中 100% 可用。在许多微服务实现中可以观察到相同的效果,其中所有其他服务都被认为是 100% 保证的。
当人们在他们呼吁使用服务网格、Apache Kafka 等时发现这种假设是错误的,并期望这些额外的基础设施能够很好地解决他们的问题——再次陷入 100% 可用性陷阱。
韧性与混沌工程
正如我在这篇文章的开头所写的,不管你怎么看:
- 在分布式系统中,跨进程边界的事情会出错。
- 你无法预测什么时候会出错。
- 它会在应用程序级别打击你。
尤其是最后一句话很重要:它将在应用程序级别打击您。这就是您需要韧性工程的原因。
韧性工程可让您系统地评估业务用例的重要性,检查潜在的故障模式并决定对策。如果操作正确,它是一种强大的风险管理工具,还可以考虑您行为的经济后果。
关于 AWS 中断,韧性工程会问如果发生更长时间的云基础设施中断会产生什么后果。如果影响太大,下一个活动是确定最关键的用例。然后识别潜在的故障场景并定义对策。
最后,这是简单的风险管理:你能承受多少停机时间,你想怎么做?
通常,韧性工程与混沌工程相辅相成。韧性工程可帮助您解决已知的故障模式,而混沌工程可帮助您检测未知的故障模式(并验证韧性措施的有效性)。
与探索性测试类似,您可以模拟任意故障情况并观察系统如何响应它。请注意,您始终小心控制故障模拟(称为“实验”)的“爆炸半径”,即限制实验的潜在影响。
通常,你会在所谓的“游戏日”中捆绑一整套实验。在更高级的组织中,您不断运行故障模拟并观察结果。
即使这个术语听起来有点儿戏,混沌工程也绝不是一场游戏。它是风险管理的重要组成部分。如果您有必须启动并运行的关键用例,则需要探索未知的故障源。在分布式系统中,这不是可选的,但可以决定成败。
您可能会争辩说您没有时间或预算。好吧,步履蹒跚的公司可能采取同样的方式。问题是:这些公司在停电期间没有完成韧性和混乱工程作业,损失了多少金钱和声誉?他们中的一些人可能无法幸免于难。
因此,您需要问自己一个问题:您负担得起吗?
就个人而言,我认为大多数公司都不能忽视韧性和混沌工程。他们中的一些人仍然忽略它,希望事情会顺利进行。但如果涉及风险管理,希望是一个糟糕的顾问。
总结起来
这篇博文比我预期的要长得多,而且我承认我只是触及了表面。我的主要信息是:
- 说在中断期间运行在其基础设施上的应用程序停机是 AWS 的唯一错误,IMO 是不正确的。
- 步履蹒跚的公司对分布式系统的影响不够了解,并陷入了 100% 可用性陷阱。
- 步履蹒跚的公司对 SLA 的评估不够好。从 SLA 的角度来看,中断是意料之中的事。
- 韧性工程有助于评估和减轻可用性,从而降低经济(或更糟)风险。这不仅仅是一场 IT 秀,而是业务和 IT 的共同努力。
- 混沌工程通过发现未知的故障模式来增强韧性工程。
- 韧性和混沌工程是当代风险管理的重要、非可选工具。忽略它们意味着让自己步履蹒跚——或者更糟。
还有很多话要说,但帖子已经太长了。我将在以后的帖子中更详细地讨论讨论的主题。但是现在,我将把它留在那里,希望我能给你一些想法来思考。