为了寻找卡布奇诺、奶酪面包和可以查看电子邮件的地方,Silvia走进了一家咖啡店。连接到Wi-Fi热点后,一个强制门户提示她登录,并提供了几个第三方身份验证选项。当她点击其中一个访问令牌提供商时,她的浏览器显示“无互联网连接”错误。由于她无法访问网络,她无法获得OAuth令牌——而且没有令牌她也无法访问网络。
这个短篇故事说明了系统设计的一个关键细节,这个细节很容易被忽视,直到发生中断:循环依赖。
如果您曾经将钥匙锁在房屋或汽车内,您就会熟悉依赖循环。没有钥匙您无法打开锁,但是没有打开锁您也无法拿到钥匙。有些循环是显而易见的,但更复杂的依赖循环可能很难在它们导致中断之前被发现。跟踪和控制依赖性的策略对于维护可靠的系统是必要的。
正如循环咖啡店的故事中所描述的锁定一样,这只是依赖性管理对可靠性具有关键影响的一种方式。如果不了解任何系统依赖的其他系统,您就无法推断任何系统的行为,也无法保证其性能特征。如果不了解服务是如何相互关联的,您就无法理解系统中一部分额外延迟的影响,或者中断将如何传播。依赖性管理还会如何影响可靠性?
没有任何服务的可靠性可以超过其关键依赖项。8 如果依赖项没有得到管理,具有严格 SLO1(服务级别目标)的服务可能会依赖于被认为是尽力而为的后端。如果后端恰好具有高可用性或低延迟,这可能会被忽视。然而,当该后端开始完全按照其 SLO 执行时,它将降低依赖于它的服务的可用性。
分布式系统应该在尽可能接近生产环境的环境中进行测试。7 如果在测试环境中省略了非关键依赖项,则测试无法识别由它们与系统交互引起的问题。这可能会在代码在生产环境中运行时导致回归。
配置不当的生产服务器可能会意外地依赖于其开发或 QA(质量保证)环境。反之亦然:配置不当的 QA 服务器可能会意外地将虚假数据泄漏到生产环境中。实验可能会无意中向生产服务器发送请求并降低生产数据。依赖性管理可以在这些问题变成中断之前暴露它们。
灾难发生后,可能需要启动公司的所有基础设施,而没有任何东西已经在运行。循环依赖可能会使这不可能:前端服务可能依赖于后端,但后端服务可能会随着时间的推移而被修改为依赖于前端。随着系统随着时间的推移变得越来越复杂,这种情况发生的风险也会增加。隔离引导环境还可以提供强大的 QA 环境。
在具有边界安全模型的网络中,访问一个系统可能意味着可以不受限制地访问其他系统。9 如果攻击者攻破了一个系统,那么依赖于它的其他系统也可能面临风险。了解系统是如何互连的对于检测和限制损害范围至关重要。您还可以在部署 DoS(拒绝服务)保护时考虑依赖性:一个对额外负载具有弹性的系统可能会向下游发送请求给其他准备不足的系统。
当依赖循环涉及用于访问和修改服务的机制时,它们是最危险的。操作员知道采取哪些步骤来修复损坏的服务,但是没有该服务就无法采取这些步骤。这些控制循环通常出现在访问远程系统时。禁用远程服务器上的 sshd
或网络的错误可能会阻止连接到它并修复它。当损坏的设备负责路由数据包时,可以在更大的范围内看到这种情况:整个网络可能会因为错误而离线,但是网络中断使得无法连接到设备并修复它。网络设备依赖于它自己提供的网络。
依赖循环也可能扰乱从两次同时中断中恢复。与隔离引导场景一样,两个已经发展为相互依赖的系统在两者都不可用时无法重新启动。作业调度系统可能依赖于写入数据存储系统,但是该数据存储系统可能依赖于作业调度系统来为其分配资源。
循环甚至可能影响人为流程,例如随叫随到和调试。在一个例子中,源代码控制系统中断导致源代码存储库和文档服务器都不可用。获取源代码控制系统的文档或源代码的唯一方法是恢复同一个系统。如果没有关于系统内部结构的关键信息,随叫随到的工程师的响应受到了严重阻碍。
在单体软件开发的时代,依赖性管理相对清晰。虽然单体二进制文件可能执行许多功能,但它通常提供一个单一的故障域,其中包含二进制文件的所有功能。跟踪少量大型二进制文件和存储系统并不困难,因此单体架构的所有者可以轻松绘制依赖关系图,可能如图 1 所示。
软件行业向微服务模型的转变使依赖性管理变得更加困难。正如 Leslie Lamport 在 1987 年所说,“分布式系统是指即使您不知道存在的计算机发生故障也可能导致您自己的计算机无法使用的系统。”5 大型二进制文件现在经常被分解成许多较小的服务,每个服务都服务于一个单一目的,并且能够独立失败。零售应用程序可能有一个用于渲染店面的服务,另一个用于缩略图,还有更多用于货币兑换、结账、地址规范化、调查等。它们之间的依赖关系跨越了故障域。
在她在 2017 年 Velocity NY 会议上的演讲中,金融时报的 Sarah Wells 解释了她的开发团队如何管理超过 150 个微服务——而这仅仅是金融时报技术资产的一部分。Squarespace 正在分解其单体4,并且已经拥有超过 30 个微服务。像谷歌、Netflix 和 Twitter 这样的大公司通常拥有数千个微服务,这使得依赖性管理问题超出了人类的能力范围。
微服务提供了许多优势。它们允许独立的组件发布、更平滑的回滚和多语言开发,以及允许团队专注于代码库的某个领域。然而,它们不容易跟踪。在一家拥有超过一百个微服务的公司中,员工不太可能绘制出正确的图表,或保证他们做出的依赖性决策不会导致循环。
单体服务和微服务都可能遇到由隐藏依赖性引起的引导问题。它们依赖于对解密密钥、网络和电源的访问。它们也可能依赖于外部系统,例如 DNS(域名系统)。如果单体的各个端点通过 DNS 到达,则保持这些 DNS 记录更新的过程可能会创建循环。
SaaS(软件即服务)的采用创建了新的依赖性,这些依赖性的实现细节是隐藏的。这些依赖性受到前面提到的延迟、SLO、测试和安全问题的约束。未能跟踪外部依赖性也可能引入引导风险。随着 SaaS 变得越来越流行,并且越来越多的公司外包基础设施和功能,循环依赖性可能会开始跨越公司。例如,如果两家存储公司要使用彼此的系统来存储引导映像,那么影响两家公司的灾难将使恢复变得困难或不可能。
从本质上讲,服务依赖性是对服务远程数据片段的需求。它可以是存储在文件系统中的配置文件,数据库中用户数据的行,或者是后端执行的计算。服务访问此远程数据的方式可能有所不同。为了简单起见,我们假设所有远程数据或计算都由通过 RPC(远程过程调用)提供服务的后端提供。
正如刚刚看到的,系统之间的依赖循环会使灾难后几乎不可能恢复。关键依赖项的中断会传播到其依赖项,因此开始恢复数据流的自然位置是依赖链的顶部。然而,对于依赖循环,没有明确的开始恢复工作的位置,因为每个系统都依赖于链中的另一个系统。
识别循环的一种方法是构建一个依赖关系图,表示系统中的所有服务以及它们之间交换的所有 RPC。首先构建图,方法是将每个服务放在图的节点上,并绘制有向边来表示传出的 RPC。一旦所有服务都放置在图中,就可以使用常见的算法(例如通过深度优先搜索找到拓扑排序)来识别现有的依赖循环。如果没有找到循环,则意味着服务的依赖关系可以用 DAG(有向无环图)表示。
当找到循环时会发生什么?有时,可以通过反转依赖关系来消除循环,如图 2 所示。一个例子是通知系统,其中发送者将新数据通知控制器,然后控制器从发送者拉取数据。这里的循环可以通过仅允许发送者将数据推送到控制器来轻松消除。循环消除也可以通过将功能拆分到两个节点来实现——例如,通过将新数据通知移动到第三个系统。
有些依赖关系本质上是循环的,可能无法消除。复制服务可能会定期查询其副本,以加强数据同步和完整性。3 由于所有副本都代表一个单一服务,这将在图中表示为自依赖循环。通常可以允许自依赖,只要它们不妨碍系统的隔离引导并且可以从全局中断中正确恢复。
另一个本质上是循环的依赖关系发生在作为 worker-controller 系统实现的数据处理管道中。2 Worker 将其状态告知控制器,并且当 worker 变为空闲时,控制器会将任务分配给 worker。worker 和控制器之间的这种循环依赖关系可能无法消除,除非完全更改处理模型。在这种情况下可以做的是将 worker 和控制器分组到一个超节点中,表示一个单一服务。通过对图的所有强连通分量重复此边收缩,并考虑它们的用途和实际可行性,您可以获得原始图的 DAG 表示。
在某些环境中,您可以通过仅了解现有的依赖关系图获得巨大的好处。在其他环境中,确定现有状态是不够的;需要机制来防止新的不良依赖关系。此处检查的两种方法,依赖关系跟踪和依赖关系控制,具有不同的特征
• 跟踪依赖关系是一种被动方法。 您可以使用日志记录和监控来记录哪些服务相互联系,然后在将来查看这些数据。您可以通过创建可以有效查询的数据结构或通过可视化关系来理解依赖关系。
• 控制依赖关系是一种主动方法。 在设计和实现的几个阶段,您可以识别并避免不良依赖关系。此外,您可以在代码在生产环境中运行时阻止建立连接。如果您等到依赖关系已经被使用和监控之后,那么防止它可能引起的问题就为时已晚。
这些方法是重叠的(例如,在依赖关系控制期间收集的数据当然可以用于跟踪),但让我们分别看一下它们。
最初,依赖关系跟踪通常采用存储在工程师头脑中的信息和在白板图表中可视化的形式。这对于较小的环境来说是足够的,但是随着系统变得越来越复杂,服务地图变得过于复杂,任何人都无法记住。工程师可能会对由意外依赖关系引起的中断感到惊讶,或者他们可能无法推断如何将服务及其关联的后端从一个数据中心移动到另一个数据中心。在这个阶段,组织开始考虑以编程方式生成系统的视图。
不同的环境可能会使用不同的方法来收集有关服务如何互连的信息。在某些环境中,防火墙或网络设备可能会记录哪些服务相互联系的日志,并且可以挖掘这些日志以获取依赖关系数据。或者,一组构建在通用框架上的服务可能会导出关于每个连接的标准监控指标;或者可以使用分布式跟踪来暴露请求通过系统的路径,突出显示连接。
您可以聚合任何可用的信息源并创建一个依赖关系图,将数据处理成通用结构并对其进行优化以运行查询。从那里,您可以使用图上的算法来检查它是否是 DAG,使用 Graphviz 和 Vizceral 等软件对其进行可视化,或者公开每个服务的信息,可能使用一个标准仪表板,每个服务都有一个页面。
通过持续监控系统之间的流量并立即将其集成到图中,新的依赖关系可能会在它们到达生产环境后不久被看到。即便如此,信息仅在新依赖关系创建并已在使用后才可用。这对于依赖关系跟踪来说是足够的,在依赖关系跟踪中,您想要描述现有系统的互连并了解新的互连。然而,防止依赖关系需要依赖关系控制。
与依赖关系跟踪一样,依赖关系控制通常从使用存储在工程师头脑中的信息的手动过程开始。开发人员可能会在所有设计文档中包含建议的后端列表,并依靠同事对现有系统的了解来标记危险。同样,这对于较小的环境来说可能足够了。随着服务的诞生、增长、变化和被弃用,数据可能会很快变得陈旧或难以管理。如果以编程方式强制执行依赖关系控制,则效果最佳,并且在添加依赖关系控制时需要考虑几个方面。
在谷歌从事依赖关系管理工作时,我们发现最好从客户端-服务器连接的客户端(即,即将依赖于另一个服务的服务)的角度来考虑控制依赖关系。通过拥有启动连接的代码,客户端的所有者对存在的依赖关系拥有最大的控制权和可见性,因此可以更早地检测到潜在的问题。客户端也最容易受到考虑不周的依赖关系的影响。
虽然服务器的所有者可能出于容量规划或安全等原因而想要控制其客户端是谁,但不良依赖关系更可能影响客户端的 SLO。由于客户端需要来自服务器的某些功能或数据才能实现其自身的功能或性能,因此它需要为服务器端中断做好准备。另一方面,服务器不太可能注意到其某个客户端的中断。
一种依赖关系控制方法是在构建时分析客户端的代码并限制依赖关系。然而,二进制文件的行为将受到它接收的配置和环境的影响。相同的二进制文件在不同的情况下可能具有非常不同的依赖关系,并且二进制文件内部代码的存在并不是该二进制文件是否依赖于另一个服务的合理预测指标。如果使用标准机制来指定后端或连接类型——例如,如果所有后端都在配置中提供而不是在代码中提供——这可能是一个值得探索的领域。
如果在运行时应用限制,则限制最有效。通过拦截并可能阻止正在建立的连接,您可以确定您正在检查正在运行的系统的实际行为,而不是基于代码或配置进行推测。为了避免浪费工程精力,应该在软件开发生命周期的早期阶段尽可能早地实施对服务可能联系的后端的限制。在系统已经上线和使用后更改系统的架构要昂贵得多。6 通过在软件开发的所有阶段(开发、测试、金丝雀发布和运行)应用相同的限制集,可以及早识别任何不受欢迎的依赖关系。
运行时强制执行有几种选择。正如依赖关系跟踪一样,现有的基础设施可以被重新用于依赖关系控制。如果所有服务间连接都通过防火墙、网络设备、负载均衡器或服务网格,则可以对这些基础设施服务进行检测,以维护可接受的依赖关系列表,并丢弃或拒绝任何与列表不匹配的请求。然而,在客户端和服务器之间的某个点静默地丢弃请求可能会使调试变得复杂。由于未获批准的依赖关系而被丢弃的请求可能与服务器或中间设备的故障无法区分:连接可能看起来只是消失了。
另一种选择是使用专用的外部依赖关系控制服务,客户端可以在允许每个新的后端连接之前查询该服务。这种外部系统的缺点是增加了延迟,因为它需要额外的请求来允许或拒绝每个后端。当然,依赖关系控制服务本身也成为服务的依赖项。
在谷歌,我们在连接建立时将限制添加到代码中,从而获得了最大的成功。由于谷歌拥有一个同构环境,并且所有连接都使用标准的 RPC 机制,因此我们能够修改 RPC 代码,使每个新的后端都与“依赖关系控制策略”(为每个二进制文件提供的额外配置选项)相匹配。
依赖关系控制策略由服务预期启动的 RPC 名称的 ACL(访问控制列表)组成。出于性能原因,该策略在启动期间由服务序列化和加载。如果策略无效(由于语法错误或数据损坏),则不会使用该策略,并且依赖关系控制不会激活。如果策略正确,它将变为活动状态,并且所有传出的 RPC 都将与它匹配。如果触发了 RPC 但策略中不存在,则它将被标记为拒绝。被拒绝的 RPC 通过监控报告,以便服务所有者可以审计它们并决定正确的行动方案:如果 RPC 不是期望的依赖关系,则从二进制文件中删除 RPC;如果它确实是必要的新依赖关系,则将其添加到 ACL。
此伪代码显示了如何实现 RPC 的授权
func isAllowedByPolicy(rpc, acl)
foreach expectedRPC in acl
if rpc == expectedRPC
# 如果 RPC 在 ACL 中列出,
# 则应允许它。
return true
# 如果 RPC 与 ACL 上的任何项都不匹配,
# 则应拒绝它。
return false
为了防止生产中断,允许服务所有者选择是强制执行策略并丢弃被拒绝的 RPC,还是软应用策略并允许被拒绝的 RPC 通过。大多数服务所有者选择在其测试和 QA 环境中强制执行策略,以便他们在新的依赖关系到达生产环境之前捕获它们,然后在生产环境中软应用策略。即使在软应用策略时,监控和警报仍然可用于将被拒绝的 RPC。
如前所述,ACL 可以基于关于二进制文件触发的 RPC 的历史信息,但这意味着在没有依赖关系控制的情况下允许二进制文件运行并为生产数据服务一段时间。此外,根据传出流量的可变性和多样性,某些 RPC 可能很少见或仅在特殊情况下触发,例如关闭或崩溃。在这种情况下,它们可能不会出现在历史数据中,并且必须手动添加到 ACL。因此,建议服务所有者在生产环境中强制执行依赖关系控制之前,长时间以软应用模式运行。
按名称授权 RPC 是控制由单个后端唯一服务的 RPC 的好方法,但这并不能涵盖前面强调的所有依赖关系问题。一个例子是数据完整性案例,其中相同的 RPC 由生产服务器和测试服务器提供服务。除非策略可以区分服务后端,否则您无法阻止生产 RPC 到达测试实例。此外,ACL 可以为依赖关系提供严格的锁定,但它们本身并不足以防止依赖循环。
为了防止这些其他依赖关系问题,RPC 可以在服务器组内隔离。要做的第一个决定是选择一个 DAG 模型,该模型将决定服务器集之间的通信。一种防止循环的简单模型是表示服务器预期启动顺序的图。这是一个系统的堆叠或分层模型,如图 3 所示。分层模型强化了服务器永远不会依赖于高于它们所在的层,从而可以从下到上顺序引导服务器。服务器只能依赖于同一层或更低层的服务器。
底层服务只能依赖于本地静态数据才能引导,永远不能依赖于另一个服务提供的数据。在谷歌,引导系统所需的全部静态数据(例如,编译后的二进制文件、配置文件、系统文档、根密钥等)被称为背包。
层可以有子层,以防止同一层中的服务器之间出现依赖循环。子分层是一个较小的问题,通常可以由一个团队处理,而无需与其他团队协调。
分层模型非常适合启用单个系统的引导,但它仍然没有解决隔离生产和测试环境或限制不同地理区域之间通信的问题。为了解决这类问题,您必须能够将服务器分组到断开连接的集合中;这称为隔离模型。与分层模型允许向下方向的依赖关系不同,隔离模型不允许不同组件之间的依赖关系。在图 4 的示例中,不允许产品 Jupiter、Earth 和 Mars 相互交换 RPC。因此,不允许它们相互依赖。
在 DAG 模型中概括依赖关系授权的一种方法是让有向边表示可以发送到关系。图上的每个节点都有一个自引用边(即,它们可以向自身发送 RPC)。此外,可以发送到关系是传递的: 如果 A 可以向 B 发送 RPC,并且 B 可以向 C 发送 RPC,则 A 可以向 C 发送 RPC。请注意,如果 B 可以向 A 发送 RPC,并且 B 可以向 C 发送 RPC,这并不意味着 A 可以向 C 发送 RPC,反之亦然。可以发送到是一种有向关系。如果存在双向的可以发送到关系(从 A 到 B 和从 B 到 A),这将构成一个循环,并且该模型将不是 DAG。
DAG 模型中授权 RPC 的伪代码可以写成
func isAllowedByModel(rpc, model)
clientNode = model.resolveNode(rpc.sender)
serviceNode = model.resolveNode(rpc.receiver)
return model.hasTransitiveConnection(clientNode, serviceNode)
隔离模型可以与分层模型结合使用,从而加强每个区域的隔离引导,如图 5 所示。
组合不同模型的伪代码可以如下所示
func isAllowedByAllModels
foreach model in modelCollection
# 检查模型是否允许 RPC。
if !isAllowedByModel(rpc, model)
return false
# 如果没有模型拒绝 RPC,则应允许它。
return true
在组合模型时要小心,不要通过组合互斥的模型来隔离关键组件。通常,简单的模型更容易理解,并且更容易预测组合的结果,例如此处描述的分层模型和隔离模型。预测两个或多个复杂模型的组合逻辑可能具有挑战性。例如,假设有两个基于机器地理位置的模型。很容易看出,从一个模型分配位置“东京”,从另一个模型分配位置“伦敦”将导致一个空集,因为没有机器可以同时位于伦敦和东京。同时,如果有两个基于位置的树模型——例如,一个用于城市、时区和国家/地区,另一个用于都会区、投票区和国家/地区——可能很难验证哪些值组合将返回非空集。
随着大规模相互依赖的软件系统的增长,依赖关系管理是系统和软件设计的关键部分。大多数组织将受益于跟踪现有依赖关系,以帮助建模其延迟、SLO 和安全威胁。许多组织还会发现限制新依赖关系的增长对于数据完整性以及降低中断风险很有用。将基础设施建模为 DAG 将更容易确定没有依赖关系会阻止系统的隔离引导。
可以通过观察系统的行为来跟踪依赖关系,但是要在依赖关系问题到达生产环境之前预防它们,需要更积极的策略。实施依赖关系控制可确保每个新的依赖关系都可以在投入使用之前添加到 DAG。这使系统设计人员可以自由地在有价值的地方添加新的依赖关系,同时消除来自不受控制的依赖关系增长的大部分风险。
1. Beyer, B., Jones, C., Petoff, J., Murphy, N. R. (Eds.). 2016. 站点可靠性工程:谷歌如何运行生产系统, 37-40. O'Reilly Media.
2. Beyer, B., Jones, C., Petoff, J., Murphy, N. R. (Eds.). 2016. 站点可靠性工程:谷歌如何运行生产系统, 第 25 章:“数据处理管道”。O'Reilly Media.
3. Chang, F., et al. 2006. Bigtable:结构化数据的分布式存储系统;https://static.googleusercontent.com/media/research.google.com/en//archive/bigtable-osdi06.pdf。
4. Kachouh, R. 2017. Squarespace 服务的支柱。Squarespace 工程博客;https://engineering.squarespace.com/blog/2017/the-pillars-of-squarespace-services。
5. Lamport, L. 1987. 发送给 DEC SRC 公告板的电子邮件消息;https://www.microsoft.com/en-us/research/publication/distribution/。
6. Saini, A. 2017. 在 SDLC 的每个阶段修复错误需要多少成本?Synopsis;https://www.synopsys.com/blogs/software-security/cost-to-fix-bugs-during-each-sdlc-phase/。
7. Seaton, N. 2015. 为什么在整个测试过程中环境的保真度很重要。Electric Cloud;http://electric-cloud.com/blog/2015/09/why-fidelity-of-environments-throughout-your-testing-process-is-important/。
8. Treynor, B., Dahlin, M., Rau, V., Beyer, B. 2017. 服务可用性的计算。acmqueue 15(2);https://queue.org.cn/detail.cfm?id=3096459。
9. Ward, R., Beyer, B. 2014. BeyondCorp:企业安全的新方法。;login: 39(6), 6-11;https://ai.google/research/pubs/pub43231。
微服务的隐藏红利
微服务并非适用于每家公司,而且这个过程并不容易。
Tom Killalea
https://queue.org.cn/detail.cfm?id=2956643
与 Werner Vogels 的对话
从亚马逊技术平台学习
https://queue.org.cn/detail.cfm?id=1142065
大规模失败
快速变化下的可靠性
Ben Maurer, Facebook
https://queue.org.cn/detail.cfm?id=2839461
Silvia Esparrachiari Ghirotti 拥有圣保罗大学分子科学学士学位以及计算机视觉和人机交互硕士学位。她 8 年前加入 Google 担任软件工程师,并曾在社交产品、用户数据隐私和打击滥用行为方面工作。她目前领导团队开发依赖控制工具。
Tanya Reilly 是 Squarespace 的基础设施首席工程师。她此前在 Google 花费了 12 年时间来提高底层服务的弹性,包括引入分层依赖控制模型。她曾在会议上发表演讲,内容涉及站点可靠性和软件故障,并在 noidea.dog 上撰写博客。
Ashleigh Rentz 是一位技术作家,她的兴趣包括无责的事后分析和可穿戴技术。她在 Google 工作了 14 年,担任过各种职位,最近为 SRE 和 Google Cloud Platform 编写内部文档。
版权 © 2018 由所有者/作者持有。出版权已许可给 。
最初发表于 Queue vol. 16, no. 4—
在 数字图书馆 中评论本文
Niklas Blum, Serge Lachapelle, Harald Alvestrand - WebRTC - 开放 Web 平台的实时通信
在这个疫情时期,世界比以往任何时候都更依赖于基于互联网的 RTC(实时通信)。在过去十年中,RTC 产品的数量呈爆炸式增长,这在很大程度上是由于更便宜的高速网络接入和更强大的设备,同时也归功于一个名为 WebRTC 的开放、免版税的平台。WebRTC 正在从实现有用的体验发展到在疫情期间对数十亿人继续工作和教育以及保持至关重要的人际联系至关重要。WebRTC 未来的机遇和影响确实令人着迷。
Benjamin Treynor Sloss, Shylaja Nukala, Vivek Rau - 重要的指标
衡量您的站点可靠性指标,设定正确的目标,并努力准确地衡量这些指标。然后,您会发现您的服务运行得更好,停机时间更少,用户采用率也更高。
Diptanu Gon Choudhury, Timothy Perrett - 为互联网规模服务设计集群调度器
希望构建调度系统的工程师应考虑他们使用的底层基础设施的所有故障模式,并考虑调度系统的操作员如何在租户系统所有者进行故障排除期间配置补救策略,同时帮助保持租户系统的尽可能稳定。
Štěpán Davidovič, Betsy Beyer - 金丝雀分析服务
期望从事产品开发或可靠性工作的工程师具备统计知识是不合理的;消除这个障碍导致了 CAS 的广泛采用。CAS 已被证明即使对于不需要配置的基本案例也很有用,并且显着提高了 Google 的发布可靠性。影响分析表明,CAS 可能已经预防了数百起值得事后分析的停机事件,并且不使用 CAS 的团队的事后分析发生率明显更高。