到目前为止,我们已经在现代软件系统背景下引入了可观测性。因此,重要的是了解可观测性在其他现代化实践中所扮演的角色,如DevOps、站点可靠性工程(SRE)和云原生运动。本章会研究这些运动如何放大对可观测性的需求,并将其纳入它们的实践。
可观测性并不存在于真空中;相反,它既是DevOps、SRE和云原生运动的结果,也是不可分割的一部分。与可测试性一样,可观测性是这些系统的属性,可以提高对它们的理解。可观测性和可测试性需要持续投资,而不是一次性添加,或拥有一刀切的解决方案。随着它们的改进,作为开发人员的你和系统的最终用户都会获得好处。通过研究为什么这些运动产生了对可观测性的需求并整合其使用,你可以更好地了解为什么可观测性已成为一个主流话题,以及为什么越来越多的团队正在采用这种做法。
与软件交付团队在20世纪90年代至21世纪初采用的单体和瀑布开发方法不同,现代软件开发和运维团队越来越多地使用云原生和敏捷方法。特别是这些方法使团队能够自主地发布功能,而无须将其影响与其他团队紧密耦合。松散的耦合释放了几个关键的业务利益,包括更高的生产率和更高的获益能力。例如,能够根据需求调整单个服务组件的规模,并在大量虚拟的和物理的服务器上集中资源,这意味着业务受益于更好的成本控制和可扩展性。
要了解更多关于敏捷和云原生方法论的好处的示例,请参阅DevOps Research and Assessment(DORA)上Nicole Forsgren等人撰写的“2019 Accelerate State of DevOps Report”。
然而,云原生在复杂性方面有很大的权衡。引入这些功能经常被忽视的一个方面是管理成本。具有动态控制的抽象系统带来了突现复杂性和非分层通信模式的新挑战。旧的单体系统不那么突现复杂性,因此更简单的监控方法就足够了。你可以轻松推理这些系统内部正在发生的事情,以及在哪里可能出现看不见的问题。今天,大规模运行云原生系统需要更先进的社会技术实践,如持续交付(continuous delivery)和可观测性。
云原生计算基金会(CNCF)将云原生定义为“在现代动态环境中构建和运行可扩展的应用程序……[云原生]技术使松散耦合的系统具有弹性、可管理性和可观测能力。通过与健壮的自动化结合,它们允许工程师以最少的工作量频繁地、可预测地进行高影响的更改”。通过最小化繁重的体力劳动(重复的人工工作)并强调可观测性,云原生系统使开发人员具有创造力。这个定义不仅关注可扩展性,还关注作为目标的开发速度和可操作性。
为了进一步了解消除重复工作意味着什么,我们推荐由Betsy Beyer等人编辑的
Site Reliability Engineering
(O’Reilly)第5章。
向云原生的转变不仅需要采用一整套新的技术,还需要改变人们的工作方式。这本质上是社会技术性的转变。从表面上看,使用微服务工具链本身没有对采用新的社会技术实践有明确要求。但为了实现技术所承诺的好处,改变工作习惯也是必要的。虽然从既定的定义和目标中应该可以明显看出这一点,但团队通常会采取几个步骤,然后才意识到他们的旧工作习惯并不能帮助他们解决这项新技术带来的管理成本。这就是为什么成功采用云原生设计模式,与使用可观测系统以及DevOps和SRE实践是密不可分的。
同样,DevOps和SRE都强调了缩短反馈循环和减少重复工作的愿望。DevOps通过文化驱动开发和运维团队之间的合作,提供“更有价值、更迅速、更安全、更快乐” [1] 。SRE将系统工程和软件技能集结合在一起,通过开发软件系统而不是手动工作来解决复杂的操作问题。正如我们将在本章中探索的,云原生技术、DevOps和SRE方法以及可观测性的结合比它们单独的每个部分都更强大。
可观测性的目标是提供一定程度的自我审查,帮助人们对其系统和应用程序的内部状态进行推理。这种状态可以通过各种方式实现。例如,你可以使用日志、指标和链路追踪的组合作为调试信号。但就如何实现可观测性而言,这些并没有说清楚。
在单体系统中,你可以预测潜在的故障领域,因此可以自己调试系统,通过使用详细的应用程序日志记录或粗略的系统级指标(如CPU/磁盘利用率)并结合顿悟来实现适当的可观测性。然而,这些传统工具和本能技术将不再适用于云原生系统机遇带来的一系列新的管理挑战。
云原生定义提到的示例技术包括容器、服务网格、微服务和不可变的基础设施。与虚拟机和单体架构等传统技术相比,容器化微服务本质上引入了新问题,例如组件之间相互依存的认知复杂性、容器重新启动后丢弃的瞬态以及单独发布的组件之间的不兼容版本控制。不可变的基础设施意味着ssh进入主机进行调试不再可行,因为它可能会扰乱该主机上的状态。服务网格添加了一个额外的路由层,提供了一种强大的方法来收集有关服务调用如何发生的信息,但除非你稍后可以分析,否则该数据的用途有限。
调试异常问题需要一套新的功能,以帮助工程师从系统中检测和理解问题。当特定事件发生时,分布式链路追踪等工具可以帮助捕获系统内部的状态。通过向每个事件添加许多键值对形式的上下文,你将对系统所有部分中通常隐藏且无法推理的内容创建广泛而丰富的视图。
例如,在分布式云原生系统中,你可能会发现很难通过使用日志或其他不相关的信号来调试跨多台主机出现的问题。但是,通过使用信号组合,你可以从高水平的服务指标开始,系统地深入异常行为,不断迭代,直到发现与哪些主机最相关。通过主机分割日志意味着你不再需要像对单体系统那样集中保留和索引所有日志。要了解单体系统或分布式系统中子组件和服务之间的关系,你以前可能需要将所有系统组件的关系保留在脑海中。
相反,如果你可以使用分布式链路追踪来分解和可视化每个单独步骤,那么你只需要了解依赖项的复杂性,因为它们会影响特定请求的执行。了解哪些调用和接收代码路径与每个服务的哪些版本相关联,可以让你发现反向兼容性问题以及任何破坏兼容性的更改。
可观测性提供了一个共享的上下文,使团队能够以有凝聚力和理性的方式调试问题,无论系统的复杂性如何,而不是要求一个人的大脑保留系统的整个状态。
DevOps和SRE团队的工作是了解生产系统和驯服复杂性。因此,他们很自然地会关心其构建和运行的系统的可观测性。SRE专注于根据服务级别目标(SLO)和错误预算(error budget)来管理服务(参见第12章和第13章)。DevOps专注于通过跨职能实践来管理服务,开发人员对其生产中的代码负责。成熟的DevOps和SRE团队不是从列举潜在宕机原因的大量告警开始,而是观测导致用户体验受损的任何可见症状,然后使用可观测性工具深入了解相关的原因。
从基于原因的监控转向基于症状的监控意味着你需要的是能够解释你在实践中看到的故障,而不是列举越来越多的已知故障模式的传统方法。团队可以专注于系统筛选假设,以及为实际系统故障设计缓解措施,而不是浪费大部分时间来应对一系列与最终用户可见性能无关的虚假告警。我们会在第12章更详细地介绍这一点。
除了故障/修复等场景采用可观测性外,具有前瞻性的DevOps和SRE团队还使用功能标志(feature flagging)、持续验证(continuous verification)和事件分析(incident analysis)等工程技术。可观测性通过提供有效实践这些用例所需的数据来增强这些用例。让我们探索观测能力如何赋能这些工程:
混沌工程和持续验证
这些要求你具有可观测性,以“检测系统何时正常,以及随着实验方法的执行,它如何偏离该稳态” [2] 。如果不能了解系统的基线状态,不能预测测试中的预期行为,不能解释与预期行为的偏差,你就无法有意义地进行混沌实验。“注入混乱之前,如果你不知道系统在当前状态下的表现,那么进行混沌工程是没有意义的。” [3]
功能标志
这在生产中引入了标记状态的新组合,你无法在预生产环境中进行详尽的测试。因此,你需要观测能力来理解每个功能标志对每个用户的单独和集体影响。当一个端点可以根据调用它的用户和启用的功能标志以多种方式执行时,逐个组件监控行为的概念就不再成立。
渐进式发布模式
这些模式(如金丝雀和蓝/绿部署)需要观测能力,以有效知道何时停止发布,并分析系统偏离预期是否是发布的结果。
事件分析和无指责的事后检讨
这些要求你构建关于你的社会技术系统的清晰模型——不仅是技术系统内部发生的事情,还有人类操作员认为的事件期间正在发生的事情。因此,健壮的可观测性工具通过提供事后的书面记录和细节来提示回顾作者,从而促进了出色的复盘。
随着DevOps和SRE实践的不断发展,以及平台工程作为一门总括学科的发展,更多的创新工程实践将不可避免地出现在你的工具链中。但是,所有这些创新都将建立在以可观测性为核心来理解现代复杂系统的基础上。向DevOps、SRE和云原生实践的转变创造了对可观测性等解决方案的需求。反过来,可观测性也增强了采用其实践的团队的能力。
[1] Jonathan Smart,“Want to Do an Agile Transformation? Don’t. Focus on Flow, Quality, Happiness, Safety, and Value”( https://oreil.ly/KQEy9 ), July 21, 2018.
[2] Russ Miles, Chaos Engineering Observability (Sebastopol, CA:O’Reilly, 2019).
[3] Ana Medina,“Chaos Engineering with Ana Medina of Gremlin”( https://oreil.ly/KdUW9 ), o11ycast podcast,August 15, 2019.