
什么是可观测性?指标、日志与调用链概览
软件和云工程生态系统最近已经从单一架构转向了分布式世界。工程师们意识到,分散的、专门化的服务(被称为微服务)可以更好地扩展,并能提供必要的解耦,从而实现更有效的维护、升级和扩展。
然而,开发人员和工程师们很快意识到,连接分布式环境所需的“线”的数量可能会以惊人的速度快速增长。
像 Kubernetes 这样的工具承诺能简化、组织和自动化这个过程。一个新的时代带来了以前在全球范围内闻所未闻的解决方案——从内容分发到叫车并实时观看其抵达。
这篇博客将探讨可观测性,讨论其在实践中的解决方案、指标,以及各种实施挑战。
涵盖的内容:
- 可观测性与监控:关键区别
- 可观测性的三大支柱
- 使用 OpenTelemetry 实施可观测性
- 被监控的可观测性指标类型
- 实施可观测性指标时的挑战与考量
什么是可观测性?
可观测性是根据系统产生的数据(通常是日志、指标和调用链)来衡量其内部状态的能力。它使团队能够在复杂的分布式环境中发现、调查和解决问题。
在 DevOps 和云原生系统中,可观测性超越了简单的监控,它不仅能告诉你出了什么问题,还能提供上下文洞察,让你了解系统为何以某种方式运行。日志提供详细的事件记录,指标提供随时间变化的量化数据,而调用链则展示了请求在服务间的流向。
可观测性是一个贯穿始终的关注点,它渗透到每一段代码或基础设施中。这意味着它不应干扰业务逻辑,也不应影响基础设施的架构方式。然而,它必须像一只无处不在、洞察一切的眼睛,实时“监视”你的分布式架构中发生的一切。我们将在后面的章节中看到如何在实践中实现这一点。
可观测性与监控:主要区别
软件行业一直在不遗余力地开发工具和实践,以简化复杂系统的操作并防止灾难。自动化的 CI/CD 流水线可防止代码损坏,基础设施即代码(IaC)流水线可建立可重复、可预测的环境,而编排器中的自愈机制则有助于保持工作负载的可用性。
监控是一种实践,它涉及在系统中定义和跟踪各种指标,以确保系统在其已知参数范围内运行。它非常有用,并且与自动化警报相结合,可以帮助工程师了解何时何地出了问题。内存使用率、CPU 时间、响应时间和整体延迟中的异常和模式都可能是其指标。
然而,需要预先定义指标的这一事实,以及它们的黑盒性质,也正是它们的局限性所在。这就是为什么行业的重点正在扩大,不仅包括是什么和何时,还包括为什么和如何,并认识到监控是可观测性的一个子集。
可观测性和监控是两种相关的实践,它们之间存在细微的差别,但这些差别可以增强对系统的信心,并对系统性故障采取主动方法。尽管意外停机可能会带来严重的后果,但可观测性仍然常常被视为事后诸葛亮。
可观测性的三大支柱
可观测性依赖于将网络中所有服务的元数据进行关联,然后以易于理解、可交互的方式呈现出来。这样,即使系统正常运行,工程师和 DevOps 团队也能观察、调查并理解系统的行为。
那么,这些元数据是什么?我们又如何将它们关联起来呢?在整个文献中,可观测性的三大支柱被反复提及:
- 指标 (Metrics)
- 日志 (Logs)
- 调用链 (Traces)
其他一些,比如事件和配置文件(profiles),偶尔也会被提及,理论上它们可以为系统增加更多的上下文和可观测性。
1. 指标 (Metrics)
可观测性指标是量化的数据点,从系统中收集以监控其性能、健康状况和行为。它们能帮助工程师理解系统随时间的变化,并识别异常或故障。
指标可以在不同层面进行定义,包括:
- 容器层面(CPU、磁盘和内存使用情况)
- 部署层面
- 应用层面(响应时间和错误率)
- 服务层面(可用性和服务状态)
- 以及其他
这些指标通常包括 CPU 使用率、内存消耗、磁盘 I/O、网络流量、请求速率、错误率和延迟。
指标是时间序列数据,针对随时间的存储和查询进行了优化,通常会在 Prometheus、Grafana 或 Datadog 等监控工具中进行聚合和可视化。与提供详细或上下文信息的日志和调用链不同,指标提供快速、高层次的洞察,非常适合用于警报和趋势分析。
2. 日志 (Logs)
日志是详细的、带时间戳的特定系统事件记录。它们可以按级别进行分类(例如,开发时启用的调试日志,始终启用的警告和错误日志,或用于指示有用信息或审计的各种信息日志)。
日志是观察系统及其健康状况的好方法。然而,对于分布式架构来说,日志会迅速变得难以管理,因为一个请求通常需要经过多个服务才能完成响应或执行某个操作。
此外,由于日志通常由各种不相关的组件发出,且没有统一的结构,日志本身并不能天然地相互关联——可观测性的进步旨在改变这种现状。
3. 调用链 (Traces)
调用链是一种信号,用于端到端地跟踪分布式系统的请求,记录它们流经多个服务的全过程。如果服务被正确地植入了埋点(instrumented),调用链是一种非常方便的机制,可以追踪请求如何在服务之间流动,以及它们在服务内部所走的路径。
正确应用调用链所获得的洞察力是巨大的,但要实现端到端的正确追踪也极具挑战性。有些组件会发出调用链信息,而有些则不会,这可能导致调用链“断裂”或不透明,从而限制了其作用。
幸运的是,业界正在朝着开放的、与供应商无关的调用链标准靠拢。我们已经看到几乎所有现代编程语言都有了对应的埋点库(instrumentation libraries),还有可以为不同层次的常见服务(例如负载均衡器、数据库、缓存和其他服务)“启用追踪”的插件。
使用 OpenTelemetry 实现可观测性
随着系统的发展,人们越来越清楚地认识到,需要一种通用的、标准化的、与供应商无关的格式来表达指标 (metrics)、日志 (logs) 和调用链 (traces),以便它们能够以流线化的方式被引导到适当的位置并进行进一步处理。
这促成了一项名为 OpenTelemetry 的巨大工作。当时有两个现有的替代方案,OpenTracing 和 OpenCensus,这两个项目很快意识到,它们平行的地位正在分散开发者社区,这与它们都试图实现的目标完全相反。于是,这两个项目合并了,OpenTelemetry 应运而生。
它于 2019 年被 CNCF 接受,并于 2021 年进入孵化成熟度级别。自那时起,OpenTelemetry 已成为事实上的行业标准,并可与多个可观测性后端互操作(Elastic、Datadog、New Relic、Honeycomb、Prometheus、Grafana 等)。
可观测性埋点 (Observability Instrumentation)
自动和零代码埋点 (Automatic and zero-code instrumentation)
自动埋点无需更改代码即可提供即时可见性。它能从 HTTP 请求、数据库查询和外部 API 调用中捕获数据,通过“广撒网”的方式,自动从常用的库和框架中收集遥测数据。
虽然它提供了广泛的覆盖,但却缺乏针对你业务逻辑的特定上下文。自动埋点是入门的好方法,但最好转向更高级的埋点方式,以便根据你的需求进行定制。
手动和程序化埋点 (Manual and programmatic instrumentation)
手动埋点弥补了自动埋点无法触及的空白。它为你提供了对实现的更多控制,可以捕获你可能遗漏的自定义指标,并允许你删除不需要的内容。这种方法需要添加代码片段来生成调用链、指标和日志。
关键问题在于:什么值得手动埋点? 你应该专注于应用程序独有的关键业务工作流、错误情况和性能瓶颈。
另一种方法,程序化埋点 (programmatic instrumentation),在自动和手动方法之间提供了一种折衷方案。它在提供更大控制权的同时,只需要对代码进行最少的更改。当需要自动方法无法提供的特定埋点功能时,这种方法尤其有效。
数据采集 (Data collection)
对于开发和小规模环境,直接将数据导出到后端效果很好,并且无需额外基础设施即可快速实现价值。而对于生产环境,数据采集器 (collectors) 优势更为明显。
数据采集器负责处理重试、批量处理、加密和过滤敏感数据。它们将数据处理从你的应用程序中卸载,从而减少资源消耗。
数据采集器充当中央处理中心。它通过接收器 (receivers) 接收遥测数据,通过处理器 (processors) 进行处理,并通过导出器 (exporters) 导出。这种架构为将数据路由到多个目的地提供了灵活性。
可观测性实现指南与最佳实践
如前所述,可观测性是一个跨领域的问题,这意味着它将无处不在并涉及每一个人。它不是可以“部分”完成的事情。那么,我们该如何实施呢?
让我们看看下面的实施指南
-
管理者应该理解这项工作的益处,尊重其所需的努力,并在团队中明确分配资源,将其视为一个同等重要的项目,而不是一个事后补救的工作。
-
架构师和产品经理应该规划企业架构和部署图,并确定:
- 所有自定义应用程序代码
- 所有后端服务(数据库、消息队列、缓存层)
- 第三方依赖(外部或供应商提供的组件,例如支付网关、身份提供商或其他 API)
- 集群服务
- 网络和安全层,并绘制出核心业务流程图
-
开发者应该通过特定语言现成的 SDK 或自动埋点库来实现遥测,并通过配置定义OTel 终端,将数据发送到该终端。
-
DevOps 和平台团队应该配置正确的导出器 (exporters) 和采集器 (collector) 服务来接收遥测数据,部署一个或多个可观测性后端来可视化调用链和日志,并进行必要的连接。
-
工程师还应该启用其他相关的插件,例如用于 Nginx 的 otel 模块或用于 PostgreSQL 的 pgotel 模块。同样,基础组件,例如 Kubernetes 集群本身,也应该被配置为发出遥测数据。
-
最后,QA、开发和 DevOps 团队应该熟悉成功的 OpenTelemetry 实施所提供的丰富的可观测性信号和功能,并根据他们的需求定制他们偏好的后端解决方案,从而相应地增强他们的工作流程。
收益和最佳实践
一个配置良好的可观测性设置(如上所述)可能看起来需要大量工作,但它几乎总能带来回报。通过最少的培训,并依赖于用户友好的可观测性后端,担任不同角色的个人都可以探索数据。
-
QA 或管理者可以检查响应时间趋势或失败事务率,以了解某个特定的趋势。
-
开发者可以尝试理解一个漫长请求流的成功和失败路径,而无需单独监控每个容器的日志。
-
基础设施工程师也可以监控特定 Pod 的 CPU 或内存使用情况,或其自动扩缩的行为。
-
支持团队成员可以快速查明出了什么问题,从特定的 trace-id 开始调查,该 trace-id 是被选中并放置在 traceparent 头部中的值。这个过程使得采集器和后端能够组装和关联该请求的所有遥测数据,并以一种友好、直观、可调查的方式呈现出来。
可观测性实施的最佳实践包括
- 从简单开始:在添加基于代码的埋点之前,先尝试使用自动、零代码埋点。这种方法可以提供即时价值,同时帮助你确定需要自定义埋点的特定领域。
- 利用上下文和属性:通过属性 (attributes),你可以为遥测数据添加上下文。上下文帮助你理解在何种情况下收集了指标。包括环境详情、用户信息和操作细节。但是,要避免属性膨胀 (attribute bloat)。过多的属性会增加数据量并使分析复杂化。
- 监控性能影响:你应该持续监控埋点对性能的影响,因为 OpenTelemetry 可能会给你的应用程序增加开销。尝试使用批量处理 (batching) 来减少网络开销。批量处理器在导出数据之前会收集多个 Span。还应考虑不同测量类型的基数 (cardinality)。
- 基数 (Cardinality) 是属性的唯一组合的数量。更高的基数提供了更精细的洞察,但也会增加复杂性和成本。另一个需要考虑的领域是采样 (sampling),因为高吞吐量系统往往会生成大量的遥测数据,管理这些数据可能会很昂贵。
可观测性监控指标类型
当你的系统面临意外负载时,哪些指标最重要?哪些信号能在用户察觉问题之前就发出警报?
为你的特定情况确定合适的可观测性指标,能让你主动管理系统,而不是被动救火。
典型的可观测性指标包括:
- 延迟(Latency)
- 吞吐量和请求率(Throughput and request rates)
- 错误率(Error rates)
- CPU 和内存使用率(CPU and memory usage)
- 磁盘 I/O 和存储性能(Disk I/O and storage performance)
- 网络性能指标(Network performance metrics)
- 服务水平目标(SLOs)
- 用户体验关联(User experience correlation)
延迟(Latency)
延迟衡量从请求发起到着手响应完成之间的时间。该指标直接影响用户满意度和业务成果。
需要监控两种关键的延迟类型:单个操作的请求延迟和完整用户工作流的端到端延迟。高延迟通常预示着系统架构中存在瓶颈。
吞吐量和请求率(Throughput and request rates)
吞吐量衡量系统在单位时间内完成的工作量,它计算成功完成的请求、事务或任务的数量。请求率专门跟踪传入需求与系统处理能力之间的关系。
这些指标有助于识别容量限制和扩容需求。监控请求模式可揭示用户行为趋势。高峰期的流量需要与非高峰期不同的资源分配。
错误率(Error rates)
错误率衡量失败请求占总请求的百分比。该指标直接关系到系统可靠性和用户满意度。不同类型的错误需要不同的响应策略。
什么是可接受的错误率?行业标准通常将关键服务的错误率目标定在 0.1% 以下。然而,可接受的阈值取决于你的具体业务需求和用户期望。
CPU 和内存使用率(CPU and memory usage)
CPU 使用率衡量处理器的工作负载与其可用容量之间的关系。高 CPU 使用率表明计算瓶颈或低效的代码执行。内存使用率跟踪 RAM 的消耗和潜在的内存泄漏。
持续的高 CPU 使用率会导致潜在的延迟和系统不稳定性。内存耗尽则会引起应用程序崩溃和服务降级。这两个指标都需要通过适当的警报阈值进行主动监控。
采用现代方法,可观测性系统甚至可以自动调整 Kubernetes 环境中的 CPU 和内存请求与限制。
磁盘 I/O 和存储性能(Disk I/O and storage performance)
磁盘 I/O 衡量对存储系统的读写操作。高磁盘利用率会造成影响系统整体性能的瓶颈。存储指标包括吞吐量(每秒字节数)和操作率(IOPS)。
磁盘 I/O 监控对于依赖大量数据库的应用程序尤为重要。缓慢的磁盘性能会层层影响应用程序,最终影响用户体验。
网络性能指标(Network performance metrics)
网络利用率衡量带宽消耗与可用容量之间的关系。数据包丢失和网络错误则表明存在连接问题。现代微服务架构严重依赖网络性能。
较新的方法依赖于 服务网格(service mesh) 实现,它提供详细的网络监控以识别通信瓶颈。
服务水平目标(SLOs)
服务水平目标(SLOs)建立内部性能目标和基准,提供可量化的目标来指导工程决策和基础设施设计。
SLOs 能够明确责任并驱动工程优先级。未能达到 SLO 会触发调查和改进工作。
用户体验关联(User experience correlation)
通过与用户体验关联,技术指标才变得有意义。高延迟与用户沮丧和流失相关,而错误率则直接影响用户满意度和留存。
应用程序性能指数(Apdex) 根据响应时间对用户满意度进行量化。Apdex 将技术性能转化为与业务相关的满意度指标。低 Apdex 分数表明存在需要注意的用户体验问题。
哪些指标最有价值? 什么能让一个指标真正有价值?可操作的指标能带来具体的改进,而那些无法驱动决策的虚荣指标则浪费了监控资源。
可观测性的挑战与考量
虽然这一切听起来很棒,但我们必须至少提及一些你在组织中启动可观测性实施之前应考虑的因素。
1. 时间和精力的投入
确保整个组织的人员都理解其益处、熟悉相关工具并深入实施,可能是一个耗时的过程。在较小的系统或停机损失不那么严重的情况下,这可能不值得投入。
2. 工具的复杂性
正如你现在所了解的,可观测性不仅仅是一种服务或一种语言,它是一个由多种组件组成的混合体,包括规范、协议、语义约定、库和 SDK,以及用于数据摄取和可视化的服务。如果没有正确的领导,很容易在“谁负责什么”这个问题上感到迷茫或不明确。
3. 数据量
所产生的日志和遥测跟踪信息量,可以轻易地超过作为典型业务运营一部分而处理或检索的实际数据量。
如果未应用适当的采样、聚合和过滤规则,可观测性可能会增加系统开销。幸运的是,遥测领域的持续努力已经提供了多种配置选项,并就如何高效实施它们提供了指导。
关键要点
在本文中,我们探讨了可观测性如何从一项“锦上添花”的技术,演变为一项“不可或缺”的技术。我们回顾了其实施的多个方面、关键指标、最佳实践以及所面临的挑战。
尽管有效实施可观测性可能充满挑战,但其回报是巨大的。传统的监控已经演变为全面的遥测,能够将服务间的日志、指标、代码执行以及关键可观测性指标关联起来。
技术界正在关注这一趋势。大多数技术领导者都意识到,现代的云原生分布式系统所产生的数据量已远超人类的管理能力。解决方案似乎在于加倍投入,采用一个统一的可观测性平台,并投资于 AIOps,它有望通过遥测数据更快地识别问题。
联系我们
有任何云成本管理的需求或问题?欢迎通过以下方式联系我们!
公众号
企业微信客服
业务咨询
技术社区
地址
北京市海淀区自主创新大厦 5层