发布于 2026-01-06 2 阅读
0

谷歌和亚马逊带来的 7 个网站可靠性经验教训

谷歌和亚马逊带来的 7 个网站可靠性经验教训

像谷歌和亚马逊这样的公司分享了很多关于他们如何解决特定技术问题的优质内容。在今年的 re:Invent 大会上,亚马逊发布了Amazon Builders' Library(亚马逊构建者图书馆) 。这是一个文章合集,探讨了亚马逊在架构和软件交付流程中采用的方法。同样,谷歌也在其免费的 SRE(站点可靠性工程)书籍中分享了一系列关于站点可靠性工程的宝贵经验

在这篇文章中,我们将探讨我们可以从这两个优秀的资源中学到的 7 个网站可靠性经验教训。

1. 使警报可操作

良好的监控是一门精妙的艺术。谷歌 SRE 书籍中的这一章涵盖了有效监控系统所需的一切,可谓一站式指南。它阐述了监控的意义、内容和方法。我们监控代码库的 pull request 模板中实际上包含了这一章的部分内容。它曾多次帮助我重新思考我想要如何监控某些东西:

When creating rules for monitoring and alerting, asking the following questions can help you avoid false positives and pager burnout:

- Does this rule detect an otherwise undetected condition that is urgent, actionable, and actively or imminently user-visible?
- Will I ever be able to ignore this alert, knowing it’s benign? When and why will I be able to ignore this alert, and how can I avoid 
  this scenario?
- Does this alert definitely indicate that users are being negatively affected? Are there detectable cases in which users aren’t being 
  negatively impacted, such as drained traffic or test deployments, that should be filtered out?
- Can I take action in response to this alert? Is that action urgent, or could it wait until morning? Could the action be safely 
  automated? Will that action be a long-term fix, or just a short-term workaround?
- Are other people getting paged for this issue, therefore rendering at least one of the pages unnecessary?
Enter fullscreen mode Exit fullscreen mode

2. 防止警觉疲劳

处理大量警报确实令人疲惫不堪。除了需要频繁切换上下文之外,每个警报都是一个全新的、可能令人倍感压力的局面,需要你进行评估。人们常常会开始臆测警报的影响或原因,或者开始忽略那些频繁触发的警报。在谷歌SRE书籍的某一章节中,对“过多”的警报量给出了一个非常具体的定义:

我们发现,平均而言,处理值班事件所涉及的各项任务——根本原因分析、补救措施以及后续活动(例如撰写事后分析报告和修复漏洞)——需要 6 个小时。因此,每个 12 小时的值班班次每天最多可以处理 2 起事件。

基于此,他们表示大多数日子里应该不会发生任何事故。

我发现,回顾并分析上个月的所有警报是一个非常好的练习。这样做可以让你很快注意到哪些警报触发频繁。你可能还会发现一些当时不太明显的模式,例如某些警报总是在周三早上触发。这样做,然后使用上面的清单检查触发的警报,将有助于提高警报的质量。

3. 模拟停电

我非常喜欢模拟故障这种练习调试的方法。它能让你更安全地了解系统运行机制。它还能帮助你更好地理解以往的故障案例,并找出避免类似故障再次发生的有效方法。谷歌就将灾难角色扮演作为一种新员工入职工具,用于在SRE团队中不同经验水平的成员之间分享知识,同时也是一种有趣的练习。

除此之外,除了角色扮演之外,你还可以通过某种方式将故障注入到你的实际系统中。这种做法,结合对故障影响的假设,被称为混沌工程。如今有很多工具可以让你以任何你能想到的方式手动制造应用程序的故障。如果你想入门或了解更多关于如何正确进行混沌工程的信息,我强烈推荐阅读Adrian Hornsby 的这些博客文章

4. 防止因失败而进行的更改

让系统具备“自愈”能力固然诱人,但大多数情况下,当故障持续发生时,自动化变更反而会使我们更难理解究竟发生了什么。很多时候,自动化变更甚至会使情况变得更糟。一个常见的例子是,当集群中的某个节点宕机时,系统会重新分配或重新分片数据。由此产生的数据传输和负载,其负面影响可能比节点本身宕机的影响更大。在考虑基础设施冗余时,务必同时考虑冗余基础设施发生故障时应该采取的措施。虽然这并非总是可行,但理想情况下,最好什么都不用做。

我在 AWS re:Invent 大会上听了几场演讲,亚马逊的工程师们在演讲中介绍了他们如何构建系统架构以提高可靠性。会上,一个相关的概念被反复提及,并被命名为“静态稳定性Static stability”。AWS 在 Amazon Builders 库中发表了一篇很棒的文章,解释了他们如何将静态稳定性应用于 EC2 和其他 AWS 服务。

5. 防止级联故障

当一个应用程序发生故障时,不应该导致其他应用程序也随之崩溃。您可以通过以下几种方式防止级联故障:

  • 使用熔断机制。这意味着,如果某个服务当前似乎无法正常工作,就停止调用它。这样可以避免因请求过多而导致你所依赖的服务过载。
  • 采用巧妙的重试策略
  • 为请求添加超时设置。应用程序请求过多导致过载是造成故障的常见原因,这会导致请求速度变慢。如果没有超时设置,所有依赖于该应用程序的服务也会变慢。

6. 对基础设施进行分片

分片混洗是另一种降低故障影响的有效方法。在大多数示例中,它被用于防御应用程序的恶意客户端攻击。首先,您可以将客户端分片到多个组中。每个分片都拥有独立的应用程序运行基础设施。这样,当恶意客户端攻击应用程序时,只有分配到同一分片的客户端才会受到影响。这可以显著降低单个恶意客户端造成的损失。

更进一步,您可以将每个客户端分配到两个分片中,而不是一个。这样,一个恶意客户端就可以攻击两个分片。但是,其他客户端被分配到完全相同的两个分片的概率非常小。客户端很可能会遇到其中一个分片故障,但大部分客户端可以回退到仍然正常运行的分片上。

如果以上内容让你感到困惑,请务必阅读亚马逊建站者资源库中的这篇博文。它对亚马逊建站者的运作方式进行了非常出色的解释和可视化演示。

7. 接受过时的数据

大多数情况下,显示过时的数据总比没有数据要好。你不想对自己隐瞒失败的情况,但或许你想对客户隐瞒。一个显而易见的应用场景是当前缓存结果的地方。你可以改变缓存机制,让被调用的程序主动推送结果给你。或者,你可以让缓存机制更智能一些,将(单独的)条目存储更长时间,以便在出现故障时可以回退到这些条目。

结论

希望这些建议能帮助你思考如何提高系统的可靠性。关于可靠性,有很多非常好的资源。我在本文中已经分享了一些,一定要去看看!

我很想听听你们对此的看法!

文章来源:https://dev.to/raoulmeyer/7-site-reliability-lessons-from-google-and-amazon-520a