AI 原生时代的可观测性——可观测性:将数据转化为洞察的艺术

31 阅读1小时+

如何证明可观测性的价值?关键不在于采集更多数据,而在于把这些数据转化为信息,使你的组织能够基于更充分的信息做出决策,以更高效地运营业务!

在第一章中,我们将为你概览我们认为关于可观测性你所需要了解的一切内容,包括它的历史,以及它是如何从监控演化而来的。我们将讨论如何证明可观测性的价值,并为对现代可观测性战略的任何投入提供合理依据。我们还将解释高质量可观测性数据的重要性,因为这是成功实施 AIOps 所必需的!

请准备好踏上一段关于监控的旅程,了解它如何始终帮助 IT 运维维持系统正常运行。你将学习到,随着我们开始构建更加动态的混合云原生分布式系统,可观测性是如何从监控中演化出来的。今天,它已经不只是“维持系统亮着灯”的问题;它还关乎如何利用可观测性以更具成本效益的方式运行系统,使你的软件成为竞争差异化因素——并由此提升业务产出。我们还将讨论这些年来组织内部因可观测性和人工智能(AI)而受益的新角色。这包括业务领导者、开发者、站点可靠性工程师(SRE)、可观测性专家和平台工程师。

在本章中,我们将涵盖以下几个主要主题:

  • 什么是可观测性?
  • 可观测性与分布式系统
  • 虚拟机、容器和数据库——天哪!
  • 全栈:从网络到云再到应用可观测性
  • 本书焦点的定义

什么是可观测性?

“到底谁需要可观测性?我听说它对于所交付的价值来说非常昂贵,而且我们大概没有它也能活下去!”——如果你浏览 Reddit、Stack Overflow 或 LinkedIn 这类在线论坛,你会非常常见地看到这种观点。

确实,证明一个项目的价值——无论它是围绕可观测性、AI 还是机器学习(ML)——都是一项挑战。

早在 2016 年,Gartner 就将 AIOps 定义为“将机器学习和大数据分析应用于 IT 运维的自动化和增强”。

最初,AIOps 旨在解决许多大型企业中出现的可观测性工具泛滥问题。AIOps 的核心是利用 AI 和 ML 对来自各种可观测性数据源的所有信号进行关联,以减少告警噪声。AIOps 的价值主张,是通过在极其复杂的混合云企业环境中更快识别 IT 问题的根因,来支持 IT 运维。尽管 AIOps 的承诺非常诱人,但早期解决方案面临的挑战在于:它们要运行在来自各种工具的、彼此割裂且未标准化的可观测性数据集之上。AIOps 的早期阶段需要进行大量配置,并对本地环境与云端可观测性工具之间的数据做标准化处理。由于缺乏可观测性标准,日志、指标、链路和事件之间也更难关联起来。因此,对于许多实施 AIOps 的团队而言,要向 IT 和业务领导层等所有相关利益方证明投资回报率(ROI),是一件很困难的事情!

简而言之,AIOps 1.0 大多没有兑现最初的承诺!

但自从 AIOps 这个术语最初被提出以来,时代已经变了。我们——本书作者——曾与许多成功完成 IT 运维转型的组织合作!这同样得益于可观测性解决方案的进步、新的开放行业标准的出现,以及面向可观测性优化的 AI/ML 解决方案的改进与普及。

到了 2026 年,也就是 AIOps 作为一个正式实践被命名的 10 年后,如今已经有可能兑现它最初的承诺。我们可以从像消防员一样被动应对问题,转向借助 AI 支持的现代可观测性来预防问题。在整本书中,我们会分享大量来自我们采访对象的洞见——他们的故事、最佳实践、挑战、如何证明 AIOps 价值的方法,以及他们对 AIOps 的看法!

你或许已经对这个话题形成了自己的看法——至少我们希望如此!

如果你或你的团队已经负责,或者被要求负责以下事项,那么我们假定你已经理解可观测性能带来的价值:

  • 单台服务器、服务器集群或多个数据中心的可用性
  • 确保办公地点之间的高吞吐网络
  • 维持本地基础设施与公有云厂商之间的稳定连接
  • 保持业务关键型数据库持续运行
  • 确保关键存储过程具备一定响应时间
  • Kubernetes 集群的韧性
  • 为微服务做合理容量规划,以处理突发流量
  • 审计系统安全与合规性
  • 报告与软件相关的业务影响
  • 确保业务关键软件的健康运行

无论你当前处于组织可观测性旅程的哪个阶段,在这个不断变化的世界里,本书都旨在为你提供指导,说明可观测性如何让你的工作更轻松,包括它如何更准确、更快速地洞察系统运行状况,以及如何利用可观测性来推动更好的自动化修复、成本优化和业务报告。

现代 AIOps 的目标,是改变我们运维系统的方式,也就是从对事件做出反应并恢复服务,转向在问题发生之前主动预防问题。可观测性和 AI 的进步,能够赋予 AIOps 所需的智能,使其从最初仅仅对单个告警进行降噪,发展为真正关联所有可观测性信号,从而在异常演变成问题之前识别出来。

不过,对于那些尚不熟悉监控的人来说,让我们先退一步,看看为什么以及如何从监控演进到可观测性,以及 AI 在其中所扮演的角色。

什么是可观测性,它与监控有何不同?

如果你问:“什么是可观测性?它做什么?它与监控有什么不同?”——你很可能会根据不同人的背景和经验,得到不同的答案。

让我们来问问 ChatGPT!

既然这本书既讲可观测性,也讲 AI 如何帮助组织提升其可观测性实践、改进软件交付和运维,那我们就让 AI 接受一次测试。如果我们把上述问题问给各大搜索引擎提供的任何大型语言模型(LLM),我们会得到类似下面这样的回答:

“可观测性是系统的一种特性,它允许你通过检查外部输出(如日志、指标和链路)来理解其内部状态。另一方面,监控则是收集预定义指标和阈值以跟踪系统健康状况的过程。可观测性更具主动性和调查性,能够帮助你理解问题为什么发生;而监控更偏向被动性,会在问题发生后提醒你。”
Google Search Lab – 2025 年 7 月 22 日

早期阶段:监控静态系统

我们的 AI 机器人给出的定义其实相当不错。这个定义也强调了可观测性是如何从监控中演化出来的。回顾 20 世纪 90 年代末和 21 世纪初——对于我们一些作者来说,那是监控的早期年代——监控通常是围绕预定义、众所周知的指标来进行的,例如 CPU、内存、垃圾回收、磁盘利用率、网络带宽、丢包率、服务响应时间以及数据库连接池利用率。下一步则是设定有意义的阈值,当某个指标达到一个已知的(有时甚至是拍脑袋定出来的)临界阈值时触发告警,例如 CPU 利用率大于 90%、磁盘剩余空间小于 5%,或 TCP 丢包率大于 1%。

监控解决方案能够从操作系统中拉取指标(通过 Linux 系统命令或 Windows 性能计数器),或者通过诸如简单网络管理协议(SNMP)这类标准来获取指标。为了监控业务应用,可以从操作系统提取进程指标,或者利用像广为流行的 Java Management Extension(JMX)这类接口来查询 Java 运行时和应用特定指标,例如垃圾回收、线程数和内存使用率。

由于系统在那时本质上更加静态,因此维护配置管理数据库(CMDB)来记录主机、进程和服务的全部详细信息也相对容易。监控解决方案还能够提供关键服务器、进程和应用指标的快速健康概览,如下图所示:

image.png

图 1.1:基于静态阈值的主机和关键进程的传统监控

对于那些还记得那个时代的人来说,你也知道接下来发生了什么……

更复杂、更动态系统的黎明

这种传统监控方法,对于相对静态、具有可管理且定义明确的健康指标集合的系统来说,运行得非常好。但随着 IT 系统在本质上变得更加动态和复杂,它的局限性也开始显现。过去这些年里,业内许多 IT 专家完成了以下转变:

  • 从少量物理服务器迁移到数倍数量的虚拟机(VM)
  • 将旧的单体应用重构为大量新的微服务
  • 在多个可用区或区域中为每项服务部署多个 Pod
  • 使用无服务器或 Web Assembly(WASM)技术来实现业务功能
  • 将工作负载从本地迁移到云或混合云
  • 通过特性开关实现动态发布功能
  • 集成广泛的 SaaS API 服务

这些新技术种类的出现,也要求我们采用新的方式来监控这些系统和运行时环境。对于某些系统来说,已经不再能简单地安装监控软件,或者直接查询操作系统统计数据。虚拟化平台(VMware)、云厂商(AWS、Azure 和 Google)以及软件即服务(SaaS)厂商(Salesforce、Atlassian、SAP 和 Workday)通常都提供了它们自己的内置监控方案,带有基础仪表盘和告警能力。另一种做法,则是通过某种专有接口,把部分指标或日志提取到你自己的监控系统中,例如 AWS CloudWatch API 或 Atlassian 的 Monitoring API!

这些专有 API 带来的挑战,通常包括:数据粒度不足、缺乏标准从而导致查询和解析数据需要投入大量工作,以及厂商对使用这些 API 本身所收取的额外费用——包括把数据传回企业内部监控系统所需的网络流量费用。

云原生监控无法按我们需要的方式扩展

当 Google 将 Kubernetes 捐赠给 Linux 基金会时,我们不仅看到了云原生计算基金会(CNCF)的诞生,也看到了所谓云原生架构的兴起。云原生并不局限于在公有云基础设施上运行软件;它是一套架构原则,使得在公有云、私有云或主权云之上,以动态而非静态的方式开发出数百、甚至数千个组件成为可能。

我们还要面对许多新的系统类型和层级,而它们都以各种格式、不同程度的基数和精度,产生大量额外的遥测数据。那种用单一指标配合静态阈值来判断系统健康或不健康状态的日子已经一去不复返。为了展示现代云原生系统的新复杂性,请看下面这个截图:一个相对较小的环境,仅承载 9 个应用,却依赖于 3,304 个微服务,这些微服务分布在超过 1 万个 Pod/进程之上,运行于 142 台主机和全球 7 个不同的数据中心中。

image.png

图 1.2:云原生系统在极短时间内变得极其复杂

随着系统复杂度不断增长,以及可观测性数据的爆炸式增长,我们需要一种新的方式,把这些数据转化为可执行的信息,而不至于需要雇佣并培训数百位新专家!

AIOps 2.0:为云原生 AI 时代做好准备的可观测性

对于静态系统以及可以用电子表格维护的静态阈值而言,监控曾经非常出色,而且每个孤立问题都能有清晰定义的响应措施。但由于我们的系统已经变得如此复杂和动态,监控必须演进为可观测性;同时,我们还需要自动化和 AI 来应对如此海量的数据,从而让运维人员能够更快地做出自动化决策。

AIOps 2.0(暂且这么称呼,尽管未必是最好的术语)有机会兑现 2016 年 AIOps 的最初承诺。为了应对复杂性和数据爆炸,在云原生 AI 时代,一套可观测性实现需要具备以下能力:

  • 自动发现系统组件及其关系,而不是在 CMDB 中手动跟踪主机、进程或服务
  • 自动建立基线,而不是对数十万指标手工设置阈值
  • 自动异常检测,并将季节性、服务级别目标(SLO)以及系统组件之间的依赖关系纳入考虑
  • 自动根因分析,通过端到端系统依赖关系关联异常信号
  • 自动修复,触发并验证动作,以维持系统处于健康状态

随着系统复杂性持续呈指数级增长,我们也看到数据量以同样惊人的速度增长。为了理解这些数据,可观测性需要更聪明的算法,而不是只孤立地看待每个数据点。我们需要借助 ML 和 AI 更快检测异常、理解这些异常在高度动态且彼此连接的系统组件之间所产生的影响,并利用这些数据加速对根因的修复,从而将业务影响控制在较低水平。我们还必须利用生成式 AI 和 LLM,以人类可理解的方式解释某种情形以及检测到的问题。这类系统的强大之处在于,它们已经在多年间由专家共同创造并在互联网上分享的全球知识库上进行了训练,例如 Stack Overflow 和 Reddit。这使得生成式 AI 和 LLM 能够帮助 IT 系统运维人员在系统愈发复杂的同时变得更高效。行业厂商以及分析机构提出了 AIOps 这一术语,用来描述通过应用 ML 和 AI,基于大量可观测性数据做出更优决策,从而支持 IT 运维。

在整本书中,我们将涵盖各种使用场景,并详细说明:对哪类数据应用哪种算法、针对哪些场景使用哪类模型,以及如何利用这些能力来触发动作——这正如当前关于 agentic AI 的讨论所展示的那样:它们不仅能回答问题,还能基于数据采取行动。

下面的截图展示了一套现代 AIOps 实现。我们可以看到自动发现的力量(涉及组件的完整依赖关系图)、基线建立与异常检测(服务失败率),以及根因分析(Argo CD 部署某个特定 Git 提交,作为潜在根因)。

image.png

图 1.3:AIOps——借助 AI 的力量检测根因与影响的可观测性

如今的 AIOps 解决方案还能够与你的事件响应系统集成,向责任团队发送通知,甚至触发修复动作,例如重启服务、回滚部署,或者通过基础设施即代码(IaC)发起拉取请求,以对环境进行合理扩缩容。

到这里,你应该已经对监控有了很好的理解,也明白了它在 20 世纪 90 年代末和 21 世纪初是如何围绕静态系统的健康状态进行理解与告警的。随着架构向更加动态、复杂和云原生方向演进,我们需要一种新方法来判断系统健康状况,并快速识别和修复根因,以限制潜在的业务影响。这正是现代可观测性登场的地方。

到目前为止,我们只讨论并举例说明了指标。然而,指标只是众所周知的三大可观测性支柱之一。在下一节中,我们将探讨所有与现代可观测性相关的信号。我们将讨论那些使数据采集更容易的新兴标准,并分享一些最佳实践,说明如何从每种信号中提取信息,以提升可观测性实现的质量。

三大支柱及其之外:日志、指标与链路的使用场景

在前面的简要介绍中,我们只快速看了一些围绕指标的可观测性数据示例,例如 CPU 使用率、内存消耗、垃圾回收、服务响应时间和网络丢包率。

然而,可观测性并不只是指标。可观测性社区通常会谈到可观测性的三大支柱:日志(logs)指标(metrics)链路(traces)

得益于可观测性领域的创新,尤其是在开放标准、开发框架与运行时开发者以及可观测性平台厂商的共同推动下,我们看到越来越多有用的遥测信号正在出现,并带来了大量新的使用场景。以下是一些例子:

  • 事件(Events) :Kubernetes 事件、持续集成构建事件或 GitOps 部署事件
  • 真实用户行为(Real user behavior) :打开移动应用、刷新页面帧,或改变屏幕方向
  • 代码剖析(Code profiling) :详细的 Java 或 .NET 栈跟踪
  • 安全与合规(Security and compliance) :检测存在漏洞的代码函数或库,或者检测导致不符合监管框架的配置错误

在整本书中,我们将涉及以下方面的最佳实践:

  • 如何最佳地采集信号,以及应如何补充哪些元数据
  • 需要提取哪些信息,以及应去除哪些信息
  • 需要存储哪些信息、保留多长时间,以及谁应当访问这些信息
  • 如何优化每类信号的不同成本维度
  • 如何孤立地分析这些信号
  • 如何连接不同信号(例如日志与链路)以获得更好的答案
  • 为了真正实现高水平的 AI 驱动可观测性,需要做些什么来让数据更易于被 AI 理解

虽然你可能已经熟悉单个信号,但让我们还是从对这三大支柱的快速介绍开始。

什么是指标?

指标是我们可以从众所周知的实体中采集的数值型数据,这些实体包括网络设备、服务器、进程、数据库或应用程序。指标通常反映被监控实体的当前状态,例如 CPU 使用率、内存消耗、服务响应时间以及服务失败率。持续采集这些指标,有助于我们理解系统随时间变化的行为。指标通常用于构建告警,例如在应用失败率过高时发出警报。性能工程师和 SRE 会利用指标对系统进行优化,以提升吞吐量、性能或成本效率。例如,他们可能会增加 Java 虚拟机(JVM)中的工作线程数量,以处理更多并发请求。

指标面临的关键挑战包括:指标维度的高基数、维度名称可能带来的隐私问题、大规模数据量与噪声,以及实时采集、传输和分析指标所带来的开销。

挑战:在维度数据中谨慎处理高基数与隐私问题

请避免以下常见错误:为了识别来自特定用户或 IP 地址的可疑活动,开发者很容易创建一个带有 usernameIP address 两个维度的请求计数指标。虽然创建这个指标很容易,但分析它却会带来挑战:

  • 后端数据存储必须处理潜在的数十亿个唯一 IP 地址,这使得对每个唯一 IP 地址计算或告警异常行为变得非常困难
  • 通过访问一个技术性指标(如请求计数),组织内所有人都可能看到所有用户名,这往往会带来隐私问题

关于如何正确创建和处理指标,我们在整本书中还会进一步学习很多内容。当然,线上也有大量资源介绍不同类型的指标、指标值聚合、维度等内容。

什么是日志?

日志是结构化或非结构化数据,它们来自与指标相似的实体,例如网络设备、操作系统、数据库或应用程序。日志可能是最古老的可观测性信号。如果你曾经开发过任何形式的代码,那么你很可能已经使用过 printconsole.log 语句。最初,日志主要用于故障排查,帮助开发者更好地理解代码是如何在远端系统上执行的,以及执行了哪些事务/请求,从而定位失败发生在哪里。分析日志时,开发者通常会查找错误或异常堆栈跟踪,或者查看代码中额外加入的调试信息,以便更轻松地排查问题。

自软件工程的早期阶段以来,日志已经发生了巨大演进。如今,开发者使用的大多数日志框架都输出结构化日志,并包含一组标准字段,例如时间戳(日志生成时间)、日志级别(ERROR、WARNING、INFO 或 DEBUG)、上下文(请求 ID、应用 ID 等)以及内容(实际日志消息)。日志通常通过 Fluentd、Logstash 或 OpenTelemetry(OpenTel)这类代理进行采集和增强,然后经过日志管道发送出去,在此过程中还会被进一步补充更多上下文信息,例如日志来源、服务器、Kubernetes 集群、命名空间或 Pod。

挑战:应对高体量、过量和非结构化日志

虽然日志存在多种挑战,但首要挑战在于系统往往会生成大量日志,而并不是每一条日志在日常运维中都有意义。由于许多组织运行着大量已经存在多年的软件,因此非常有可能有许多日志是非结构化的,从而难以分析。由于日志非常容易创建,我们经常看到应用存在过度记录日志的问题,而且这往往不容易控制。一个常见错误是:为了一次快速故障排查而加上的调试日志,之后却从未被删除。

由于大多数软件系统中的日志量都非常大,日志经常被认为非常昂贵。虽然这确实是事实,但我们不应第一时间责怪可观测性后端。日志很重要,但这需要良好的日志文化和自动化检查机制来把日志控制在合理范围内。

关于正确的日志管理,我们在本书中还会学习更多内容,例如如何从日志中提取指标,以及如何只存储那些对关键使用场景真正相关的日志,例如合规和安全场景。与指标一样,也请参考线上关于结构化日志与日志管道的大量资源。

什么是链路?

分布式链路(distributed traces)是三大支柱中最年轻的一支。分布式链路会跟踪单个请求在分布式系统中流经多个服务的全过程,从而洞察请求在不同组件之间的路径和性能表现。

它们最早在 21 世纪初由应用性能管理(APM)厂商引入,例如 Wily(现已归入 Broadcom)、Dynatrace、AppDynamics(现已归入 Cisco)以及 New Relic。最初它们主要面向 Java 和 .NET,这些厂商的代理可以在 JVM/.NET 运行时加载字节码时进行插桩。借助这种方式,无需对代码做手工修改。自动生成的分布式链路输出,为开发者提供了端到端视图:从 Web 请求进入 Web 或应用服务器开始,经过队列或中间件,继续流向后端服务,最终到达数据库。

分布式链路不仅是开发者理解分布式系统中动态代码执行过程的优秀调试工具,后来也常常被集成到性能测试和生产环境中,用于理解各个组件的性能与负载行为。

分布式链路必须解决的一大挑战,是将唯一的 Trace ID 从第一个服务传播到最后一个服务。这通常通过 HTTP Header、消息属性,或者在多线程代码中通过线程本地存储来实现。

过去,这一切都依赖于专有插桩和专有数据格式;而最近,这些内容已经通过 CNCF 项目 OpenTel 实现了标准化。下面的可视化展示了一个通过 OpenTel 采集的端到端链路的结构。每条链路都有唯一 ID。每一段被捕获的信息,例如 Web 请求、数据库调用或方法调用,都被表示为所谓的 span。Span 与其父 Span 以及它所属的 Trace 之间存在关联关系。

image.png

图 1.4:摘自 “Unleash the Power of Distributed Traces”——解释通过 OpenTel 采集的分布式链路结构

如果你想进一步了解分布式链路、Span 和请求的内部原理,可以观看 YouTube 视频 Unleash the Power of Distributed Traces [1]。本书中也会进一步介绍 OpenTel 的更多内容。

挑战:过度插桩、重复数据与采样问题

在过去 20 年中,厂商不断优化它们的代理,以避免过度插桩(采集过多调用或过多信息)、减少重复数据采集(同样的数据既存在于链路中也存在于日志中),并优化采样策略(决定应存储哪些数据、过滤哪些数据)。

随着许多组织试图减少对厂商代理的依赖,它们正在把代码插桩的责任转移给开发者。虽然 OpenTel 正在逐步成熟,也有越来越多开发者工具可以帮助工程师完成插桩,但对于任何计划引入分布式链路的可观测性项目来说,过度插桩、重复数据以及合理采样决策的挑战都必须被认真考虑。

超越三大支柱:基于事件、剖析与真实用户的使用场景

除了日志、指标和链路之外,我们还拥有额外的可观测性信号,它们为 DevOps 工程师、平台工程师、业务线负责人、安全团队、架构师和开发者等角色提供了更多使用场景和收益。下面是一些基于运行时或生命周期事件、真实用户监控、代码剖析和安全洞察的真实案例与使用场景。

使用场景:通过事件跟踪你的软件开发生命周期

“我的构建在哪儿?一个代码修复进入生产环境需要多久?是哪个 Git 提交刚刚把生产搞挂了?”——这些以及类似的问题,都可以通过使用可观测性来追踪你的代码和构建制品的生命周期来回答:从第一次 Git 提交开始,经过持续集成、测试、持续交付,最终发布到生产环境。

OpenTel 社区已经开始为来自 CI/CD 系统的可观测性数据制定语义约定,以使这件事更容易。像 Dynatrace 这样的厂商,也已经开始定义软件开发生命周期(SDLC)事件,以便通过摄取来自 Jira、GitHub、GitLab、Azure DevOps、Argo CD 和 Flux 等工具的可观测性数据来跟踪一个制品。

通过可观测性跟踪制品,不仅让你有机会对 DevOps Research and Assessment(DORA)这类效率指标进行报告,也能为你的 AIOps 系统提供更多上下文,以更好地识别问题根因。一旦实现,它就允许你自动定位导致生产事故的问题 Pull Request、Git 提交或流水线运行实例。

使用场景:通过提取业务事件提供实时业务洞察

“我们最新一次功能上线的业务影响是什么?自从我们为高端用户启用新的 AI 聊天机器人之后,收入增长了吗?为什么要花一周时间才能拿到更新后的业务影响报告?”——这些是我们经常从业务领导者那里听到的问题。最大的挑战在于,如何获得实时业务洞察,并理解技术变更是如何正向或负向影响业务结果的。通过使用可观测性监控这些业务 IT 系统中的日志、指标和链路,我们通常可以提取业务事件,并利用这些数据提供与技术数据相连接的实时业务报告和洞察。

举个例子,在一个电商平台中,我们可以从日志或链路中捕获购物车数量,或者要求开发者导出一个自定义指标。再结合我们掌握的终端用户额外上下文(例如 IP 地址范围),以及他们是否完成购买(成功执行购买 API 端点),我们就可以按地理区域提供“已实现价值与未实现价值”的实时报告。

现有可观测性信号的更多使用场景

在第 3 章中,我们将提供更多详细使用场景,涵盖以下领域:通过真实用户行为分析优化用户体验、通过代码剖析和实时调试提升开发效率、评估安全攻击与漏洞风险,以及通过自动验证强制性合规要求来管理合规。这些都是今天就可以利用现有可观测性信号实现的使用场景!

使用场景:随着可观测性演进,未来还会有更多

几十年前,一切始于对指标的监控,随后扩展到日志和分布式链路;而如今,它又扩展到了更多信号,并开启了前文所述的新用例。随着可观测性领域在新兴标准与持续创新的推动下不断演进,基于现有信号还会出现更多新的使用场景。也很可能会出现新的信号。在整本书中,我们将进一步深入探讨更多使用场景、最佳实践,以及组织如何将它们作为现代可观测性战略的一部分来实施!

接下来我们要回答的问题是:所有这些数据来自哪里?是否存在任何标准?还是说这一切都只能通过少数几个可观测性厂商的专有实现来完成?

多年来出现的新兴标准

早期的分布式系统监控,主要依赖标准协议,例如 SNMP,或者操作系统内建的基础监控工具和接口,以理解操作系统、运行中的进程以及承载这些进程的硬件利用情况。

从 21 世纪初开始,应用性能监控(APM)将基础系统监控提升为对分布式系统性能、韧性和执行行为的复杂、实时、端到端可观测能力。APM 厂商(Dynatrace、AppDynamics、New Relic、Datadog、Instana 等)提供了定制化的专有代理,这些代理能够在其安装的系统(Linux 或 Windows)上自动采集指标、日志和链路。从一个厂商迁移到另一个厂商并不容易,因为在数据采集和分析两侧都缺乏真正的标准,因此切换成本很高。

这大概也导致了厂商锁定(vendor lock-in)成为组织在推动现代可观测性开放标准时提得最多的理由之一。随着云原生架构,尤其是 Kubernetes 相关架构的兴起,我们看到了若干由开源社区推动的新兴标准,它们旨在标准化现代云原生分布式系统中的可观测性数据采集、转换和分析方式。

下面我们快速概览最重要的标准和开源项目。

OpenTelemetry

其中最突出的标准是 CNCF 项目 OpenTel [2]:这是一个开源可观测性框架和工具包,旨在促进链路、指标和日志的生成、导出与采集。2019 年,OpenTel 由 OpenCensus 和 OpenTracing 合并而来,最近又开始扩展到更多信号,例如代码剖析和真实用户监控。

虽然 OTel 本身并不是一个用于存储和分析数据的可观测性后端,但这一标准在整个可观测性领域激发了大量创新:

  • 插桩(Instrumentation) :社区和厂商共同为各种运行时和语言贡献自动插桩代理。
  • 采集(Collection) :OpenTel Collector 提供了一种与厂商无关的方式,用来接收、处理和导出遥测数据。社区和厂商提供了大量扩展,使 OTel Collector 成为一个非常优秀的可观测性数据管道。
  • 分析(Analysis) :通过将可观测性数据采集进行“商品化”,许多新的开源工具和厂商得以出现,它们基于纯 OpenTel 数据提供分析能力。

OpenTel 实现中的一个关键组件是 OpenTel Collector [3]。下面这张截图来自 OpenTel 官网,突出展示了它围绕 receivers(从各种数据源拉取数据)、processors(做标准化、采样、提取或增强)和 exporters(将数据发送到存储和分析后端)的可扩展架构。

image.png

图 1.5:OpenTel Collector 架构:一种与厂商无关的数据采集、处理与导出遥测方式

OpenTel Collector 还在解决我们前面讨论过的一些关键可观测性挑战中扮演了至关重要的角色:过度插桩、重复数据和采样问题。当将 OpenTel 作为数据接收器和数据管道来实现时,请务必注意其不断变化的生态系统。一定要了解你的技术栈支持情况,以及如何正确配置和规划 Collector 的容量。

大多数商业可观测性平台都支持 OpenTel,要么通过支持 OpenTelemetry Protocol(OTLP)直接从源头(已插桩的应用)接收数据,要么通过 OpenTel Collector exporter 来摄取数据。一些厂商还提供定制化的 OpenTel Collector 发行版,这些版本由厂商预配置、测试并提供官方支持。

无论你的可观测性后端是什么,请务必弄清它对 OpenTel 的支持程度,并查阅关于部署和配置开源后端工具或商业可观测性平台的最佳实践。

Prometheus

Prometheus [4] 最初由 SoundCloud 于 2012 年开始开发,是另一个非常流行的开源监控与告警系统。它的创建是为了解决当时现有监控方案的局限,尤其是多维数据模型、可扩展数据采集,以及一种名为 PromQL 的简洁而强大的查询语言。Prometheus 于 2016 年加入 CNCF,并在 2018 年毕业。与 OpenTel 相比,Prometheus 更专注于采集并存储指标,这些指标会被写入一个针对高基数优化的时序数据库,因此它非常适合实时监控和历史趋势分析。指标还可以通过键值对形式附加额外上下文,从而应对我们前面讨论过的一些挑战,例如为指标补充其来源信息以及额外的业务数据维度。

其关键架构组件如下:

  • 导出指标(Exporting metrics) :服务需要通过一个 HTTP 端点暴露指标,供 Prometheus 抓取。社区已经为各种系统、框架或 API 提供了大量 exporter(例如 Apache、Nginx、Kafka 或 BIG-IP)。开发者也可以利用各种语言的客户端库导出自己的指标。
  • 摄取指标(Ingesting metrics) :Prometheus Server 会按照周期性时间间隔,向一组配置好的目标端点(应用、服务器等)发送 HTTP 请求并进行抓取。它期望这些端点返回所请求的指标、指标类型及其值。
  • 存储指标(Storing metrics) :Prometheus Server 自带一个本地磁盘时序数据库,用于存储采集到的指标,也可以选择与远程存储系统集成。
  • 告警(Alerting) :Prometheus Server 中的告警规则会将告警发送给 Alertmanager。随后,Alertmanager 会对这些告警进行管理,包括静默、抑制、聚合,并通过邮件、值班通知系统和聊天平台等方式发送通知。
  • 可视化(Visualization) :Prometheus 通常与 Grafana 配合使用。Grafana 是一个开源分析与可视化平台,可用于在仪表盘中可视化和分析 Prometheus 指标与告警。由于大多数可观测性平台(开源和商业)都能集成 Prometheus,因此你并不局限于 Grafana。

Prometheus 被广泛采用,而且由于有大量现成 exporter,绝大多数现代软件组件都能自动提供 Prometheus 指标,这些指标既可以被 Prometheus Server 或 OpenTel Collector 抓取,也可以被你的商业可观测性平台直接采集。

在现代可观测性战略中,Prometheus 很可能会在指标可观测性中扮演关键角色。请务必了解社区关于其部署、扩展和集成的最佳实践。在整本书中,我们也会进一步提供示例和指导,说明如何将 Prometheus 集成到企业可观测性战略中。

可视化标准:Grafana 与 Perses

Grafana 是一个非常流行的开源平台,用于对来自不同来源的各种可观测性数据进行可视化和分析。Grafana 是 Prometheus 指标的默认可视化工具,你会发现社区已经为各种系统组件(例如 Kubernetes、MongoDB、Kafka 和 AWS)创建并维护了大量预配置的仪表盘。Grafana 由 Grafana Labs 开发,后者还在其多个开源项目之上提供商业产品。

虽然可用的 Grafana 仪表盘并不少,但其仪表盘文件格式并未标准化,这使得 Grafana 仪表盘难以被其他可观测性可视化方案复用。开源项目 Perses 正是为了解决这一问题,它旨在为 Prometheus 以及其他数据源提供一种开放的仪表盘规范。根据 Perses 官网的信息 [5],Perses 目前是 CNCF sandbox 项目,但已经被多个可观测性厂商以及终端企业所采用。

将数据展示、分析和告警的方式标准化,是为可观测性提供厂商中立定义的下一步。OpenTel 和 Prometheus 已经在数据采集侧很好地弱化了“厂商锁定”这一论点,而 Perses 则试图在数据可视化侧实现同样的目标。

到这里,你应该已经很好地理解了可观测性是如何从监控中演化出来的。我们讨论了超越日志、指标和链路的各种可观测性信号,涉及了数据采集和可视化的新兴标准,也说明了为什么必须借助自动化、AI 和 ML,才能真正驾驭不断增长的数据量,更好地支持所有依赖可观测性数据做出更快、更优决策的团队。但这还只是旅程的开始。接下来,我们将研究现代可观测性所解决的最大挑战之一:理解分布式系统。

可观测性与分布式系统

在本节中,我们将深入探讨分布式系统,以及随着系统愈发复杂,可观测性在其中所扮演的关键角色。

首先,把某个东西单独称作“一个分布式系统”多少有点奇怪,因为任何不是只运行在单一主机或服务器上的系统,从定义上说都是分布式系统。自从我们摆脱大型机时代早期的单体系统以来,这一点在许多几十年前就已经成立。甚至有人会争辩说,即便是在那个时候,我们也已经有了分布式系统,因为代码执行和数据存储是解耦的;因此,我们也可以说,那时已经存在一个能够执行业务功能的分布式系统。

高度分布式系统与不断增加的复杂性

近年来真正发生巨大变化的是:一个分布式系统中涉及的组件数量,这些组件跨不同平台和地点的分布方式,硬件与执行业务逻辑的代码之间新增的抽象层,以及在部署模型层面上的动态弹性。所有这些都让高度分布式系统的管理变得更加复杂。

过去只是少量物理服务器,如今变成了数倍数量的虚拟机运行在这些物理服务器之上。过去是许多虚拟机运行在少量物理机上,如今又演变为数倍数量的弹性云计算实例(例如各种规格的 AWS EC2 实例)。如果再看云原生架构,我们会看到另一个量级的增长:更多的 Pod 或无服务器函数被部署在本地或云中,并通过 Kubernetes、OpenShift 或各大云厂商提供的工作流服务进行编排。部署编排和自动扩缩容的发展,也提高了变更频率。过去按月或按周进行的部署,如今已完全自动化,并且可能每分钟发生多次。这些变更可能包括:部署新的工作负载、对现有工作负载进行合理扩缩容以应对需求增长、将工作负载迁移到不同数据中心区域以优化性能或成本,或者切换特性开关以控制应用和服务行为。

通过可观测性理解分布式系统

作为一个负责分布式系统的人,你需要能够回答几个关键问题:资产清单、依赖关系、API、健康状况、SLA 和根因。

可观测性可以帮助你回答所有这些问题,使你能够更好地理解、管理并由此更好地运营你的分布式系统。

在接下来的几节中,我们将结合示例逐一走过这些问题,并给出一些指导,帮助你评估自己的可观测性战略目前已经成熟到什么程度。

资产清单:哪些组件属于我们负责的系统?

我们需要一份主机、网络设备、Kubernetes 节点、云基础设施、进程、Pod、无服务器函数和数据库的清单。借助可观测性,我们可以洞察那些被主动监控的系统(例如通过 Prometheus 或某个可观测性代理)。它也允许我们发现那些尚未被主动监控的组件,例如分析一个已监控主机到其他 IP 地址的网络连接,或者调用云服务商或编排平台的发现 API。

在本书后续内容中,我们将详细介绍如何推广可观测性、发现盲区并提升可观测性覆盖率的最佳实践。

依赖关系:组件之间如何连接、彼此依赖?

我们需要知道垂直依赖关系(哪些组件通过网络互联)以及水平依赖关系(哪些组件运行在其他组件之上,例如进程运行在主机上)。这有助于我们理解,例如,哪些进程共享相同 CPU,或者连接到同一个数据库。

如果日志、指标和链路都被补充了它们所采集系统的元数据信息,那么它们会自动告诉我们垂直依赖关系。比如,一个进程的 CPU 使用率就包含它运行在哪台主机上的信息。对网络连接的监控以及分布式链路还能进一步告诉我们水平依赖关系,因为它们包含了哪个系统正在与哪个其他系统通信的信息。

接口/API:我们的分布式系统对消费者来说边界在哪里?

我们需要知道那些必须对用户或第三方消费者可用且可访问的关键端点(HTTP、消息系统等)。这些端点还可以通过合成检测来进行监控,以确保其可用性。

可观测性能够通过从网络流量日志或分布式链路中提取这些信息,或者从负载均衡器与 Ingress 定义暴露的端点中查询信息,帮助我们自动检测这些端点。

健康状况:所有组件都按预期运行吗?是否存在异常行为?

我们需要知道如何判断任一组件的健康状态,以便理解某个组件是否可能是某次事故的潜在根因。

可观测性帮助我们摄取组件中的日志、指标、链路和事件。然后,我们可以建立健康告警,例如 CPU 使用率过高、数据库连接超时、服务失败率过高、关键错误日志,或者服务响应时间比平时更慢。最后一个例子体现的是自动建立基线,而前面那些通常通过静态阈值来完成。

一个关键考量是:不要手动管理成百上千个告警阈值,而应结合已知健康指标的默认值、自动化基线和机器学习,把管理开销降到最低。

在本书后续,我们将通过大量示例介绍如何最佳地构建健康监控与异常行为告警。

SLA 与根因:端到端关键事务是否出现问题?为什么?

我们需要在关键事务不可用、返回结果不准确,或表现不符合预期时收到告警,以避免潜在的 SLA 影响。

可观测性不只是帮助我们在问题已经发生时收到告警。现代可观测性实现的目标,是在 SLA 被突破之前就提前发出告警。这可以通过对所有可观测性信号施加 AI,同时结合关键端到端事务中涉及哪些组件的上下文信息来完成。如果这些组件中的任何一个开始表现异常,就可以触发修复动作,在影响整个系统之前缓解问题。

在本书后面,我们会通过大量示例和最佳实践,介绍如何利用 AI 和可观测性,从被动反应式运维迈向主动式、再迈向预防式运维。

下图展示了一个简单的分布式系统,同时也说明了如何回答前面提到的所有问题:

image.png

图 1.6:可观测性为分布式系统提供洞察,包括所有组件,并突出显示正常与异常行为

对于你的 IT 环境和关键应用来说,能够回答这些问题至关重要。根据你当前可观测性实现的成熟度,这些信息可能已经可以开箱即用,也可能还需要花一些时间从多个来源中汇总出来。

你并不一定要像图 1.6 那样生成一个可视化图。但这个示例图有助于解释一个分布式系统、它的组件、依赖关系以及潜在问题。使用任何对你来说最有意义的工具或可视化方式都可以。在我们这个例子中,让我们快速根据图中的内容回答五个问题:

  • 资产清单:若干 Linux 和 Windows 服务器、Web 服务器、应用服务器以及微服务。
  • 依赖关系:通过分析分布式链路,我们知道哪些服务运行在哪些硬件之上,以及这些服务彼此如何依赖。
  • 接口/API:每个服务和 Web 服务器上的端点,可以从日志或分布式链路中提取。
  • 组件健康:一台 Linux 主机出现问题,影响了运行在其上的服务。我们可以通过对关键操作系统指标(如 CPU、内存、磁盘和网络)设置告警,以及对服务指标(如失败率或响应时间)设置告警来获得这些信息。
  • SLA 与根因:应用正在经历 SLA 违约,原因是下游某个不健康服务(Service 3)不可用,而它的根因是一台不健康的 Linux 主机。

可观测性最佳实践

在摄取日志、指标或链路时,关键是这些信号必须附带其所运行基础设施的信息。可观测性代理或像 OpenTel 这样的管道,应尽可能在靠近源头的位置增强数据。请务必采集关于底层主机、数据中心、云厂商、命名空间等信息。这能使依赖关系被正确识别出来。

在本节中已经很明显:分布式系统存在大量相互依赖关系——无论是一个故障服务影响上游服务,还是一台主机因资源不足而影响其上运行的服务。后者正是我们接下来要深入探讨的内容,因为在观察和分析分布式系统及其组件时,共享基础设施必须被充分理解!

共享基础设施及其对组件的影响

在分布式系统中,我们拥有大量共享基础设施——比如 Kubernetes 节点上所有 Pod 共享的 CPU 和内存,争抢同一台物理服务器底层硬件资源的虚拟机,或者 Linux 操作系统中共享同一块磁盘进行读写的多个进程。

从可观测性的角度来看,重要的是我们要理解:有哪些基础设施资源可用,以及是谁在使用这些资源。这使我们能够回答很多重要问题,例如“是否存在一个吵闹的邻居(noisy neighbor)在影响其他服务?”,并且打开许多有价值的使用场景,例如“我们能否优化资源利用率以节约成本?”除了 ITOps 和 SRE 之外,我们还看到 FinOps 团队也在利用可观测性优化成本,同时确保不会对满足业务目标所需的关键组件产生负面影响。

使用场景:识别 noisy neighbor

如果你曾经和室友合租公寓,还要共用卫生间,或者住在隔音很差、隔墙能清楚听到对面说话的地方,那么你就会理解 noisy neighbor 问题。

共享基础设施中也存在同样的问题。经典例子包括:虚拟机、进程或 Pod 在共享主机或节点上过度占用 CPU、内存、网络或磁盘。这种行为会影响所有其他进程,使它们变慢,甚至导致崩溃或根本无法启动。这个问题通常发生在没有设置防护边界的情况下,例如没有为 Pod 指定其可使用的内存或 CPU request 与 limit。

image.png

图 1.7:识别 noisy neighbor 需要对每个消费者(VM、进程、Pod 等)的所有关键指标(CPU、内存、磁盘等)进行细粒度可观测

关注 noisy neighbor 不仅有助于识别根因,也有助于发现某些部署缺乏必要的资源护栏。一类值得设置的告警是:如果某个进程持续使用超过其邻居 10 倍以上的资源(CPU、内存、磁盘等),那就是一个很好的行动信号。

使用场景:基于真实需求对基础设施做合理容量规划

继续沿用室友的比喻。想象一下,你租了一个有五间卧室的公寓,但你只用其中一间。这显然是一个非常大、而且很可能成本很高的公寓。共享基础设施也是一样。如果你长期拥有闲置资源,那就是应该缩减底层共享基础设施规模的信号。这样会更高效,也能节约成本。去找找你的 FinOps 部门吧;如果可观测性能自动生成一份资源利用率不高、可以降配的资源列表报告,他们一定会很高兴。

反过来的场景也同样可能发生:资源持续高利用。你可以利用可观测性分析,这种运行在共享基础设施上的服务需求增长究竟是持续性的,还是只是季节性的。如果服务利用率是持续增长的(例如过去几个月对某项服务的请求数不断上升),那么就应该要么扩大底层共享基础设施规模,要么考虑把这个工作负载迁移到一个更适合的“新家”。

从共享基础设施再往前一步,就是共享通信。分布式系统之所以能运行,是因为组件通过各种方式进行通信。接下来让我们深入看看,可观测性在同步和异步通信中的作用!

同步与异步通信

我们已经讨论过,分布式链路是识别服务之间如何通信的一种绝佳方式,因为链路技术可以追踪一个事务,从终端用户(浏览器或移动设备)开始,穿过所有中间件和微服务,最终到达后端数据库。这一切之所以可行,是因为所谓的链路上下文(trace context)会通过通信协议(HTTP、消息系统等)从调用方传播到被调用方。前面我们已经更详细地介绍过这个主题。

从可观测性的角度看,仅有分布式链路并不总是足以完全理解两个组件之间是否存在通信问题。链路中会包含调用方发起调用时的时间戳,以及被调用方接收到调用时的时间戳。但如果这两个时间戳之间的差值波动很大怎么办?如果某一条链路是 10 毫秒,而下一条却是 10 秒呢?如果某些链路显示超时错误,并且调用压根没有到达被调用方呢?这些变慢或失败的原因可能是什么?

可观测性同样有办法回答这些问题,因为我们需要把可观测性扩展到那些使同步和异步通信成为可能的架构层之中。我们说的是网络、连接和队列。所有这些层也都必须被观察,才能完整理解分布式通信中究竟发生了什么。

网络:指标或 eBPF

大多数通信都是通过网络发生的,无论是在同一台主机上,还是跨越大陆。可观测性能让我们洞察网络层中的流量(发送和接收的字节与数据包)、质量(包错误或丢包)以及连通性(会话数量和超时会话数)。这些指标通常可以从操作系统以及网络设备中直接获得。

这个领域的新玩家是 扩展 Berkeley Packet Filter(eBPF) ,其中 Cilium 是一个著名开源项目,它利用 eBPF 提供工作负载之间网络连接性的洞察。在线社区中有很多关于 eBPF 的学习资料,我们在本书后续其他使用场景中也会涉及它。现在需要知道的重要一点是:eBPF 提供了另一种方式来回答那个问题——“到底是不是网络的问题?”

可观测性提示

如果通信中出现错误或变慢,建议分析网络健康状况。可能是另一个 noisy neighbor 占满了全部网络带宽,也可能是某个故障网络组件在丢包。答案往往就藏在我们从网络层获得的可观测性洞察里。

连接:调用双方的连接池

当两个服务相互通信时,双方(通常也称作客户端和服务端)通常会先建立连接,然后再发送消息。为了更好地管理这些连接,并避免每次都新建连接,我们引入了连接池的概念。连接池管理着已经打开的连接,这些连接在需要时可以被借出用于调用,之后再归还到池中,供其他请求使用。大多数框架在连接 HTTP 端点或数据库端点时都支持连接池。连接池容量配置不当以及连接泄漏,是客户端与服务端无法高效通信时最常见的问题。一个问题是并发请求太多,超出了可用连接数量;另一个问题是连接被占用的时间超过实际所需。这两种情况都会导致下一个需要连接的请求,必须等待池中有可用连接。

可观测性提示

请查阅你的开发者所使用的应用运行时和框架文档,尤其是那些用于跨服务通信的部分。通常它们会提供与连接池大小和池使用率有关的指标。如果连接池长期利用不足或始终满载,这通常意味着容量配置不合理,或者存在错误的连接处理方式。另外,在调整连接池大小时,请记得在两端都适当调整——客户端和服务端两侧都可能存在连接池。

队列:消息的分发者

RabbitMQ、Apache Kafka、Amazon SQS、Azure Service Bus 和 Google Pub/Sub,都是分布式架构中常见的消息队列。其概念相当简单:发送方把消息推入队列,接收方从队列中取出消息并进行处理。队列通过充当客户端和服务端之间的中介,实现组件解耦。队列还可以暂时保留消息,直到有消费者取走,因此它们非常适合平滑处理突发消息流量,直到消费者有能力处理完它们。

和网络及连接池一样,队列也提供了良好的可观测性,用来帮助我们理解:队列本身是否健康、是否正在正常履行职责,还是说它本身恰恰就是某次异步通信变慢或失败的原因。

可观测性提示

请查阅你所使用队列系统的文档。很有可能已经存在一个 Prometheus exporter,或者它已经直接提供 OpenTel 指标或链路。表征健康状况的关键指标包括:队列长度、消息吞吐量、消息投递失败率,以及消息在队列中停留的时间。如果队列容量配置不合理,或者消息发送过多而消费不足,那么你会看到队列长度上升,继而导致消息在队列中的等待时间增加。你还可以通过观察消息吞吐量和投递率来判断系统运行是否稳定。

请记住,队列几乎存在于每一种分布式架构中。它们承载了绝大多数通信,因此必须确保你为它们配置了恰当的可观测性与告警机制。

随着 OpenTel 被越来越广泛地采用,端到端的同步与异步通信都将能够通过 OTel 进行链路追踪。这对所有人来说都是好消息。只要记住,在通信的两端之间,总是有某个中间组件存在——可能是网络、连接池,或者队列。它们都必须被观察,因为它们是分布式系统中任何通信的骨干。

网络、连接和队列,使不断增长的组件数量之间的通信变得更容易。而通信越容易,通常意味着跨越这些通信通道参与进来的组件就越多。这些都是需要被管理的组件和基础设施。如果你管理过动态基础设施,你大概听说过“宠物 vs 牛群(pets versus cattle)”这一类比。为了进一步理解这对可观测性意味着什么,我们在第 3 章中有一个专门小节,题为 Context is king: the quality of observability data,重点讲解如何用额外上下文(例如基础设施、服务和部署信息)去增强可观测性数据(如日志、指标、链路和事件),从而使分析和排障更容易!

在结束本章之前,我们还会分享一些关于监控虚拟机、容器和数据库的附加最佳实践,最后再通过定义本书其余部分的焦点来收尾。

虚拟机、容器和数据库——天哪!

在现代 IT 系统中,我们会遇到各种各样的技术组件和服务。在“可观测性与分布式系统”一节中,我们已经讨论过,从虚拟机到容器再到更高级形态的演进,是如何影响我们进行可观测性思考的方式的。

如今,许多运行 IT 系统的组织都拥有大量现存的 Web 服务器、应用服务器和数据库,其中一些运行在虚拟机上,一些以容器方式运行,甚至还有一些已经是无服务器函数。对于这些构成许多企业核心系统的关键组件,必须覆盖相应的最佳实践和观察方式。

观察 Hypervisor 与虚拟机

在使用虚拟机时,既要观察虚拟机本身,也要观察底层 Hypervisor。无论它是 VMware、Microsoft Hyper-V、Citrix Hypervisor、VirtualBox 还是 KVM,这些平台通常都会提供自己的可观测性工具,并伴随能够被采集进中央可观测性平台的指标。此处应重点关注的关键指标,与我们前面围绕共享基础设施讨论的内容相同:CPU、内存、存储和网络。除此之外,这些 Hypervisor 通常也会提供对其所编排虚拟机的基础监控。

可观测性最佳实践

尽管 Hypervisor 监控能够为虚拟机提供良好的基础覆盖,但仍建议深入了解虚拟机内部正在发生什么。你需要知道哪些进程和服务运行在这些虚拟机上,以及是谁在消耗多少资源。请查阅你的可观测性平台文档。通常会有某种方式——要么安装一个代理,要么通过某个扩展来查询虚拟机内部指标,而这些数据可能通过 Prometheus、Windows Management Interface(WMI)或虚拟机中操作系统提供的其他数据源拉取而来。

观察 Web 服务器与应用服务器

过去几十年里,Web 服务器和应用服务器的版图发生了巨大变化。在 APM 的早期,大多数应用运行在 IBM WebSphere、Oracle WebLogic 或 Microsoft Internet Information Server(IIS)之上。而在现代云原生架构中,我们通常会看到更轻量的服务器,例如 Apache Tomcat、JBoss 或 Wildfly,或者用诸如 Spring Boot 这样的框架在容器中承载业务逻辑。然后,还有像 Nginx 或 Traefik 这样的 Ingress 控制器或负载均衡器,承担了过去由 Web 服务器或应用服务器完成的大量请求处理与路由工作。

无论你运行的是哪个时代的组件,重要的是都要观察贯穿这些服务器的关键指标、日志,以及理想情况下的链路。

可观测性最佳实践

请查阅你的 Web 服务器和应用服务器文档。基于 Java 的组件通常会通过 JMX 暴露大量指标。很有可能也已经存在 Prometheus exporter,或者支持 OpenTel。如果你使用商业可观测性代理,请确认它是否开箱即用地支持你的服务器版本和目标平台(Linux、Windows、AIX、Solaris 等)!在所有情况下,你都需要观察有关吞吐量(请求数)、时延(请求响应时间)、服务失败率、线程池与请求池利用率、会话数量,以及 CPU 与内存利用率的指标。

观察数据库

“肯定是数据库的问题!”——就像把所有问题都怪到网络头上一样,把任何问题归咎于数据库也非常常见。根据我们的经验,数据库本身几乎从来不是真正的问题。更常见的是,应用访问数据库的方式才是性能差或失败的根因。典型例子包括:执行了过多单条数据库查询,而没有利用数据库查询语言(例如 SQL)一次性批量取数的能力;或者执行了低效查询,返回了大量根本不需要的数据。

可观测性最佳实践

在数据库可观测性方面,关键是同时关注两侧:数据库服务器本身,以及执行业务查询的应用。数据库服务器通常会自带一些内建可观测能力;例如 Oracle 和 SQL Server 都提供了非常好的工具。然而,为了让分析和根因诊断更高效,你还需要采集数据库服务器侧的指标,例如查询性能、连接、I/O 性能、存储以及会话明细。从应用侧来看,你可以分析应用日志,或者更好地,查看分布式链路,因为链路中包含了哪一个事务执行了哪一条数据库查询的信息。这能够直接洞察你的开发者执行数据库查询的效率。

下面这张截图来自视频 CSI Observability: Identifying Bad Patterns in Traces and Logs(Kubernetes Community Day Slovakia 2025),你可以在其中学习如何分析不良数据库访问模式:

image.png

图 1.8:使用 OpenTel 链路识别来自各个服务的数据库查询访问模式

如果你想了解更多数据库模式的内容,请查看 KCD Slovak YouTube 频道中的该视频(相关演讲从第 43 分钟开始)。

观察容器

事实上,容器与运行在操作系统上的普通进程并没有本质上的不同。关键区别在于用于管理容器的编排方式,这决定了你如何访问容器相关的日志和指标。本质上,你需要监控容器内运行的内容(例如 Java、Go、Python 或 .NET 应用),以及容器的编排层(例如 Docker、Kubernetes、OpenShift、Apache Mesos、Rancher 或其他托管式容器编排服务)。

可观测性最佳实践

请查阅你的可观测性解决方案文档,了解观察容器内部运行内容、采集容器日志以及获取容器编排指标的最佳实践。Prometheus、OpenTel 以及诸如 Fluentd 之类的日志框架,是目前最常见的从容器中摄取可观测性信号的方式。

特别是对于 Kubernetes 和 OpenShift 的可观测性,由于我们所见的大多数容器都是通过这些平台进行编排的,因此本书后续还会提供更多最佳实践和示例!

观察无服务器

将单体应用拆解并没有止步于以容器方式运行的微服务。无服务器框架允许你托管无状态函数,这些函数通过事件触发执行。我们可以在很多场景中看到例子,例如电商中的库存更新、结账流程和推荐引擎。在媒体场景中,经典用例包括对用户上传内容进行转码和生成缩略图。无服务器社区还维护了一个完整的 GitHub 仓库 [6],里面包含了 AWS Lambda、Microsoft Azure 和 Google Cloud Run Functions 等常见无服务器框架的示例。

可观测性最佳实践

由于无服务器函数通常托管在你无法控制的运行时之中,因此你无法观察每一个方面;例如在 AWS Lambda 上托管时,运行时由 AWS 管理。不过,几乎所有无服务器框架和运行时通常都会暴露一些指标和日志。对于无服务器,所有人都应该监控的关键指标包括:

  • Invocations:函数被执行的频率
  • Duration and errors:函数执行需要多久,以及有多少次执行因错误而中止
  • Init time:也称为冷启动(cold start),即初始化运行时所需时间
  • Concurrent executions:有多少函数在并行执行
  • Throttling:由于并发执行限制而被中止的请求数
  • Timeouts:有多少函数触及最大执行时间限制
  • Memory utilization:判断无服务器配置是否合理的重要指标

虽然上面列出的指标可以很好地帮助我们洞察总体运行时行为和错误情况,但它们并不能告诉你函数内部到底在做什么、时间花在了哪里、是否可能会超时,以及为什么会出错。除了指标之外,无服务器框架还允许开发者输出日志。随着 OpenTel 的出现,我们也看到越来越多无服务器运行时开始支持 OpenTel,例如 AWS Distro for OpenTelemetry(ADOT),或者通过使用 OpenTel 库对任意类型的无服务器函数进行插桩。

这使得你能够在无服务器函数内部获得分布式链路,并为工程师提供足够细节,以便排查执行变慢或失败的问题。

由于无服务器函数通常只是事件驱动架构中的执行片段之一,因此建议从所有相关软件组件中捕获端到端分布式链路。这通常包括处理初始请求并触发无服务器函数的 API Gateway,以及事件驱动系统中使用的各种队列或消息总线。为了实现完整的端到端链路追踪,关键是要传递我们在本章前面讨论过的链路上下文。这意味着 API Gateway 要么能够生成 Span,要么能够正确转发来自初始请求的 Trace Context,并将其继续传递给无服务器函数。这也意味着,Trace Context 必须附着在任何放入队列的消息之上,以便消息接收者能够把它作为自己的父上下文来使用。

下面这张截图展示了一条分布式链路,它横跨多个事件驱动的 Lambda 函数,这些函数通过 AWS SQS 队列连接,并对 DynamoDB 数据库服务进行更新:

image.png

图 1.9:面向事件驱动无服务器架构的 OpenTel 分布式链路

如果你想进一步了解无服务器可观测性,也可以参考 Damian Jankowski 的 GitHub 教程 Serverless Unified Observability Done Right [7]。

到目前为止,我们已经介绍了很多关于观察企业 IT 架构中相关组件的最佳实践。我们学习了如何分别观察各个组件,也学习了如何通过为日志、指标、链路和事件补充额外元数据,将这些信号关联起来,从而更好地分析跨组件和端到端事务的影响。

虽然我们已经讨论了从网络到应用整个技术栈中的所有组件,但有必要再总结一下“整体性、全栈可观测性”到底意味着什么,因为这正是成熟可观测性实现的目标。

全栈:从网络到云再到应用可观测性

本节在某种程度上是对目前所学内容的一次回顾,但它把所有内容放到了执行全栈可观测性的上下文中。全栈可观测性是优秀 AIOps 的基础。它意味着:从网络到底层业务代码(自底向上),以及从终端用户到数据库(自左向右),都要提供高质量的可观测性数据。正是这种高质量、上下文丰富的数据,决定了你加诸于可观测性数据之上的任何自动化、智能算法、AI 或 ML,最终会推动更高效、更安全的软件开发、交付和运维,还是只是徒增复杂!

什么是全栈可观测性?

当我们把这个问题问给一个聪明的 AI 聊天机器人时,我们会得到一个不错的回答:

“全栈可观测性指的是一种全面的方法,用来监控和理解整个技术栈的性能与健康状态,从终端用户体验一直到底层基础设施。它涉及在技术栈的所有层级中收集并分析遥测数据(日志、指标、链路),以深入洞察系统行为并识别潜在问题。本质上,它关心的是对系统拥有整体性视图,而不是依赖彼此割裂的监控方式。”(来自 Google 的 AI Bot,2025 年 8 月 3 日,提示词为“什么是 Full Stack Observability?”)

在“可观测性与分布式系统”一节中,我们谈到了如何利用全栈可观测性回答以下关键问题:

  • 资产清单:哪些组件属于我们负责的系统?
  • 依赖关系:组件之间如何连接、彼此依赖?
  • 接口/API:我们的分布式系统对消费者而言边界在哪里?
  • 健康状况:所有组件是否按预期运行,还是存在异常行为?
  • SLA 与根因:端到端关键事务是否出现问题?为什么?

只有当我们从终端用户一直到底层网络或后端数据库系统,真正拥有一个整体性的系统视图,并且这些数据是高质量且附带丰富上下文信息的,我们才能真正宣称:我们以正确的方式实现了可观测性——也就是全栈方式。

可观测性的目标是 100% 覆盖:从生产基础设施开始,然后向上、向左扩展

虽然这并不容易,但将可观测性覆盖率提升到 100% 是一个重要目标。这里的 100% 覆盖,并不意味着对每一笔事务都做到 100% 的端到端分布式链路覆盖,或者捕获所有组件的 100% 日志、事件或指标。大量可观测性数据其实是重复的,或者过于冗长。作为可观测性专家,关键是获得“正确的 100% 覆盖”,从而能够回答前面列出的那些问题。

许多可观测性团队会从系统中最关键的部分开始,先推广基础设施层面的可观测性(主机、网络、进程),这些部分通常承载最关键的业务应用。在此基础上,你可以沿着技术栈向上、向左和向右扩展:

  • 向上扩展技术栈:从网络和基础设施层进入应用层可观测性。一旦你知道哪些应用和服务运行在你的主机、虚拟机或 Pod 上,就可以开始从这些组件中捕获日志、指标和链路。要么为你的可观测性代理启用更深入洞察,要么开始采集 Prometheus 或 OpenTel 数据。
  • 扩展到其他系统:从你的关键系统扩展到与之相连的邻接系统。你的可观测性数据会告诉你:哪些网络连接指向当前尚未被监控的其他系统。这些可能是属于你的系统,也可能是第三方外部系统。你可以通过安装代理,或者配置 Prometheus 或 OpenTel 从这些系统采集数据,来扩展可观测性。对于第三方系统,你还可以设置合成测试,或者询问他们是否提供可通过开放标准拉取更多数据的 API。
  • 向左扩展到开发侧:可观测性不能只局限于生产环境中的关键系统。你的 SDLC 从开发阶段就开始了。因此,请把可观测性向左扩展,给工程师提供与他们未来在生产中将看到的同等级洞察。这里我们使用“expand left(向左扩展)”而不是“shift left(左移)”这个术语,是为了表明:我们不是在把更多责任推给开发者,而是在通过自助访问他们日常任务所需的数据,为他们赋予新的能力。

“可观测性太贵了,所以我们只在最关键的系统上使用它!”——如果这是你在试图推广全栈可观测性乃至推广到开发阶段时所面临的论点,那么说明你还没有真正证明现代可观测性的价值。

在第 3 章中,我们会更详细地说明如何让工程团队从可观测性数据中获得价值,而不必都变成分析可观测性数据的专家。在第 3 章的 Observability-driven development 一节中,我们会讨论如何通过实用的自助式用例,把可观测性数据转化为可执行洞察,为诸如“哪段代码应该做性能优化?”或“推荐的容器大小是多少,既能节约成本又满足可用性要求?”这类问题提供主动答案。

同一节中还会更详细介绍,如何利用可观测性追踪软件交付过程,以回答诸如“我的构建在哪儿?一个代码修复进入生产环境需要多久?是哪个 Git 提交刚刚把生产搞挂了?”这样的问题。

所以,继续读下去吧——你会学到更多可用于证明价值并逐步扩展的使用场景。

现在,是时候把这些内容落到更具体的层面了。这还只是第一章。接下来,让我们用一个指南来结束本章:说明如何利用本书余下部分,帮助你走上通往 AIOps 和现代可观测性的道路。

定义本书的重点

“到底谁需要可观测性?我听说它对于所交付的价值来说非常昂贵,而且我们大概没有它也能活下去!”——这是许多可观测性团队负责人从上层管理者那里听到的一种非常常见的论调!

你将能够证明可观测性与 AI 的价值!

证明可观测性与 AI 的价值,将会是你所面临的最大技术和组织挑战之一。为什么我们这么说?因为这是我们多年来在这一领域工作的经验总结,也是我们为写作本书所进行的大量采访中反复得到印证的事实。

我们希望,到本章结束时你已经清楚:如果方式得当,可观测性不仅不是一个昂贵的成本中心;它恰恰是现代、具备成本效率和碳效率的软件开发、交付与 IT 运维的赋能者,而这一切都将支撑你的业务目标。

在整本书中,你将学习其他组织用哪些 KPI 向管理层证明了可观测性的成功与价值。

你将把指数级数据增长视为机会!

随着我们构建越来越复杂的分布式系统,可观测性数据将呈指数级增长。作为人类,我们已经无法独自分析和管理所有这些数据。我们需要自动化、ML 和 AI 的帮助,来支持我们做出更快、更好的决策。而这些决策,必须建立在高质量且富含上下文数据的基础之上——这一点我们在本章中已经反复强调。如果我们能把这件事做好,那么不断增长的数据量就不应被视为负担,而应被看作一种机会,一座真正的数据金矿。正确挖掘这座金矿,会让你更容易证明任何可观测性实现的价值。

在整本书中,你将进一步学习如何提高可观测性数据质量、如何高效处理这些数据,以及如何确保你的可观测性和 AI 项目始终在预算范围内运行。

你将把可观测性向左扩展!

每个组织最终都会成为一家软件公司,而软件将成为竞争差异化因素。然而,软件不是静态的,也不是只在生产中才出现。软件要经历完整的 SDLC:从需求,到开发,经过测试,进入生产,最终到达用户手中——然后通过反馈形成闭环,推动软件的下一轮迭代。

正如软件要经历自己的生命周期一样,可观测性也必须如此。可观测性不能只是为了在生产中接收告警而事后补上。可观测性必须成为一种非功能性需求,在第一行代码编写之前就被清晰定义。它必须成为开发过程的一部分,以便向软件工程师即时反馈软件的质量与有效性。它还必须被用于对任何变更进行实时验证,而这些反馈又将成为下一轮迭代的输入。

在整本书中,你将学习如何把可观测性扩展到开发过程、如何定义“可观测性即代码”、如何将可观测性集成到持续集成与持续交付中,以及如何塑造一种以可观测性驱动创新与开发的文化。

你将把可观测性作为自助服务提供!

一旦可观测性成为你文化的一部分,就不可能把每一位工程师都培养成精通可观测性内外门道的专家。不是每个人都需要成为日志、指标、链路分析专家,也不是每个人都需要会分析真实用户行为或识别安全漏洞。而且这本身也没有必要。近年来,平台工程社区一直非常强调:集中化专业能力(你只需要少数专家),然后通过自助服务平台把这些专业能力提供给更多人使用。

在整本书中,你将学习如何将“可观测性即自助服务”融入现代平台。这将使你的业务团队、开发团队、SRE、安全团队、DevOps 团队、质量工程团队和 ITOps 团队,在不依赖少数专家、也不需要自己成为专家的情况下,实现对可观测性的自给自足!

你将通过 AI 驱动的自动化,释放 AIOps 的力量!

这本书不只是关于如何观察系统。它更是一本关于:如何在高质量可观测性数据之上利用 AI,从而做出更快、更好的决策,以支持你的业务目标的最佳实践指南。

在整本书中,你将学习如何真正释放 AIOps 的力量,并兑现其在 2016 年的最初承诺。你将学习如何利用 AIOps,不只是为了更高效地分析数据、辅助人类更快做出决策;真正“解放”的 AIOps 还意味着,我们能够推动自动化修复问题、合理配置环境规模、阻断恶意行为者,甚至自动化发布新的软件功能。

你将看到 Financial One ACME 的旅程

本书的目标,是通过实际示例和使用场景进行讲解,而我们在本章中已经开始这么做了。为了让内容更具代入感,我们还将引入一家虚构公司,名为 Financial One ACME。虽然它是虚构的,但其原型来自我们过去见过并合作过的许多真实组织。这是一家拥有大量现有系统、正在进行现代化改造的组织,而在这一过程中,也伴随着现代化其可观测性战略和实施 AIOps 的需求。

在整本书中,你将看到 Financial One ACME 如何应用我们的最佳实践和使用场景,把自己转型为一家更高效、更具竞争力的企业。

总结

在本章中,我们打下了基础,以便最终兑现 10 年前提出的 AIOps 承诺!我们学习了对静态系统的监控,是如何演进为对今天动态云原生架构的可观测性的。我们也学习了不同的可观测性信号、它们各自所服务的使用场景,以及为什么这些信号必须彼此关联,才能为 AI 和 ML 提供足够高质量的数据,从而输出更好的自动化洞察,而不仅仅是一堆告警。

最后,我们定义了你将在整本书中学到的内容,尤其是当你一路跟随我们虚构公司 Financial One ACME 的旅程,见证它如何现代化其可观测性战略的时候。

在下一章中,我们将聚焦于解释关于 AI 你所需要了解的一切,以便你为在可观测性数据之上正确利用 AI 做出合适选择做好准备!准备好翻开下一页了吗?

延伸阅读

[1] Unleash the Power of Distributed Traces – YouTube 视频:
www.youtube.com/watch?v=8Qu…

[2] OpenTelemetry CNCF 项目:
opentelemetry.io/

[3] OpenTelemetry Collector:
opentelemetry.io/docs/collec…

[4] Prometheus:
prometheus.io/

[5] Perses 项目:
perses.dev/

[6] Serverless examples GitHub 仓库:
github.com/serverless/…

[7] Serverless observability done right GitHub 教程:
github.com/damianjanko…