10 yeas of experience of building mission critical Fintech system handling extremely high load
Walkthroughs, tutorials, guides, and tips. This story will teach you how to do something new or how to do something better.
过去,当我们谈论后端时,我们通常指的是一个大型应用程序和一个大型数据库,日志记录足以进行监控。现在,得益于Kubernetes等技术,微服务已成为标准。应用程序数量更多、分布更广,传统的日志记录已不足以调试和诊断应用程序中的问题。
组织监控的一个极好的解决方案是 OpenTelemetry — 一个可用于分布式系统调试和性能分析的现代工具包。
本文面向希望扩展后端优化知识的 IT 专业人士。下面,我们将详细介绍 OpenTelemetry 是什么、它的关键概念以及它有助于解决的问题。如果您对 OpenTelemetry 如何改变您监控和调试后端系统的方法、提高其可靠性和效率感兴趣,请继续阅读。
大型科技公司在 2000 年代后期首次面临分布式日志记录和跟踪的挑战。2010 年,谷歌发表了一篇论文,
2014 年,Kubernetes 出现,大大简化了微服务和其他云分布式系统的开发。这导致许多公司在微服务中遇到了分布式日志记录和跟踪问题。为了标准化分布式跟踪,CNCF 采用的 OpenTracing 标准和 Google 的 OpenCensus 项目应运而生。
2019 年,OpenTracing 和 OpenCensus 项目宣布合并,更名为 OpenTelemetry。该平台结合了多年来积累的最佳实践,允许将跟踪、日志记录和指标无缝集成到任何系统中,无论其复杂程度如何。
如今,OpenTelemetry 已不仅仅是一个项目,它还是收集和传输遥测数据的行业标准。它由一群专家和 Google 和 Microsoft 等市场领先公司开发和支持。该项目不断发展,获得了新功能,以简化集成和使用流程。
OpenTelemetry 是一套全面的实践和工具,它定义了应用程序可以生成哪些信号来与外界交互,以及如何收集和可视化这些信号以监控应用程序和整个系统的状态。三种主要类型的信号是跟踪、日志记录和指标收集。
**让我们仔细看看每个组件:\
OpenTelemetry 引入了操作上下文的概念,上下文主要包括`trace_id`
(当前操作的标识符)、 `span_id`
(子请求的标识符,每个子请求的重试都有唯一的`span_id`
)等属性。
此外,上下文可以包含静态信息,例如部署应用程序的节点名称或环境名称 (prod/qa)。这些字段在 OpenTelemetry 术语中称为资源,附加到每个日志、指标或跟踪,以便于搜索。上下文还可以包含动态数据,例如当前端点的标识符 ( `http_path: "GET /user/:id/info"`
),可以有选择地将其附加到日志、指标或跟踪组。
OpenTelemetry 上下文可以使用上下文传播协议在不同的应用程序之间传递。这些协议由添加到每个 HTTP 或 gRPC 请求或队列消息标头的标头集组成。这允许下游应用程序根据这些标头重建操作上下文。
以下是上下文传播的一些示例:
B3-Propagation这是一组最初为 Zipkin 跟踪系统开发的标头( x-b3-*
)。它被改编到 OpenTracing 并被许多工具和库使用。B3-Propagation 携带trace_id
/ span_id
和一个指示是否需要采样的标志。
W3C 跟踪上下文该标准由 W3C 工作组开发,将各种上下文传播方法统一为一个标准,是 OpenTelemetry 中的默认标准。应用这些标准的一个很好的例子是跟踪通过不同技术实现的微服务的请求的执行情况,而不会影响监控和调试的准确性。
跟踪是记录并随后可视化请求通过多个微服务的路径时间线的过程。
[图片来源:https://opentelemetry.io/docs/demo/screenshots/]
在可视化中,每个条形图称为“跨度”,并具有唯一的“span_id” 。根跨度称为“跟踪” ,并具有“trace_id” ,它用作整个请求的标识符。
这种类型的可视化允许您:
trace_id
和span_id
以供其他信号使用。
尽管日志记录看似简单,但它仍然是诊断问题的最强大工具之一。OpenTelemetry 通过添加上下文信息增强了传统日志记录。具体来说,如果存在活动跟踪,则“trace_id”和“span_id”属性会自动添加到日志中,将它们链接到跟踪时间线。此外,日志属性可以包括来自 OpenTelemetry 上下文的静态信息,例如节点标识符,以及动态信息,例如当前 HTTP 端点标识符(“http_path:“GET /user/:id””)。
使用 `trace_id`,您可以找到与当前请求关联的所有微服务的日志,而 `span_id` 则允许您区分子请求。例如,在重试的情况下,来自不同尝试的日志将具有不同的 `span_id`。使用这些标识符可以实时快速分析整个系统的行为,加快问题诊断并增强稳定性和可靠性。
指标收集提供有关系统性能的定量数据,例如延迟、错误率、资源使用情况等。通过实时监控指标,您可以及时响应性能变化、防止故障和资源耗尽,并确保应用程序对用户具有高可用性和可靠性。
与 Prometheus 和 Grafana 等指标存储和可视化系统的集成使得这些数据的可视化变得更加容易,从而大大简化了监控。
[图片来源:https://grafana.com/blog/2021/06/22/grafana-dashboard-showcase-visualizations-for-prometheus-home-energy-usage-github-and-more/]
OpenTelemetry 指标收集器与 Prometheus 和 OpenMetrics 标准兼容,因此可以轻松过渡到 OpenTelemetry 解决方案而无需进行重大更改。OpenTelemetry SDK 允许将 trace_id 示例与指标一起导出,从而可以将指标与日志示例和跟踪关联起来。
日志、指标和跟踪共同创建了系统状态的全面视图:
[图片来源:https://grafana.com/blog/2020/03/31/how-to-successfully-correlate-metrics-logs-and-traces-in-grafana/]
除了三个核心组件之外,OpenTelemetry还包括采样、行李和操作上下文管理的概念。
在高负载系统中,日志和跟踪的数量会变得非常庞大,需要大量的资源用于基础设施和数据存储。为了解决这个问题,OpenTelemetry 标准包括信号采样——能够仅导出部分跟踪和日志。例如,您可以从一定比例的请求、长时间运行的请求或错误请求中导出详细信号。这种方法允许进行足够的采样来构建统计数据,同时节省大量资源。
但是,如果每个系统都独立决定要详细监控哪些请求,我们最终会得到每个请求的碎片化视图。有些系统可能会导出详细数据,而其他系统可能只导出部分数据或根本不导出。
为了解决这个问题,OpenTelemetry 的上下文传播机制会将采样标志与 `trace_id`/`span_id` 一起传输。这确保如果接收用户请求的初始服务决定应详细监控该请求,则所有其他系统都会效仿。否则,所有系统都应部分或不输出信号以节省资源。这种方法称为“头部采样”——在请求处理开始时做出的决定,可以是随机的,也可以是基于某些输入属性的。
此外,OpenTelemetry 支持“尾部采样”,即所有应用程序始终详细导出所有信号,但存在一个中间缓冲区。收集所有数据后,此缓冲区将决定是保留完整数据还是仅保留部分样本。此方法允许对每个请求类别(成功/长/错误)进行更具代表性的采样,但需要额外的基础设施设置。
Baggage 机制允许将任意键值对与trace_id
/ span_id
一起传输,并在请求处理期间自动在所有微服务之间传递。这对于在整个请求路径中传输所需的其他信息(例如用户信息或运行时环境设置)非常有用。
符合 W3C 标准的行李传输标头示例: tracestate: rojo=00f067aa0ba902b7,congo=t61rcWkgMzE,userId=1c30032v5
以下是行李使用的一些示例:
传递业务上下文信息(例如userId
、 productId
或deviceId
可通过所有微服务传递。应用程序可以自动记录此信息,从而允许通过用户上下文搜索原始请求的日志。
SDK 或基础设施的特定配置参数设置。
路由标志帮助负载均衡器做出路由决策的标志。在测试期间,某些请求可能需要路由到模拟后端。由于行李会自动通过所有服务传输,因此无需创建其他协议 - 只需在负载均衡器上设置规则即可。
请注意,虽然 Baggage 对性能的影响很小,但过度使用会显著增加网络和服务负载。请谨慎选择您真正需要通过 Baggage 传递的数据,以避免性能问题。
在基础设施层面实施 OpenTelemetry 涉及将 OpenTelemetry 后端集成到应用程序架构中并配置数据聚合基础设施。
该过程包括四个阶段:
应用程序集成在第一阶段,OpenTelemetry SDK 直接集成到应用程序中,以收集指标、日志和跟踪,确保有关每个系统组件性能的数据持续流。
配置导出器收集的数据从应用程序通过导出器路由到外部系统进行进一步处理,例如根据您的需要进行日志记录、监控、跟踪或分析系统。
聚合和存储此阶段可能涉及规范化数据、用附加信息丰富数据以及合并来自不同来源的数据以创建系统状态的统一视图。
数据可视化最后,处理后的数据将以仪表板的形式呈现在 Grafana(用于指标和跟踪)或 Kibana(用于日志)等系统中。这使团队能够快速评估系统的健康状况,识别问题和趋势,并根据生成的信号设置警报。
要与应用程序集成,您需要连接适用于所用编程语言的 OpenTelemetry SDK,或使用直接支持 OpenTelemetry 的库和框架。OpenTelemetry 通常会实现来自知名库的广泛使用的接口,从而允许直接替换。例如,Micrometer 库通常用于 Java 生态系统中的指标收集。OpenTelemetry SDK 提供了 Micrometer 接口的实现,无需更改主应用程序代码即可导出指标。此外,OpenTelemetry 还提供了旧版 OpenTracing 和 OpenCensus 接口的实现,从而有助于顺利迁移到 OpenTelemetry。
在 IT 系统中,OpenTelemetry 可以成为未来可靠、高效后端的关键。此工具简化了调试和监控,还为深入了解应用程序性能和优化提供了新的机会。加入 OpenTelemetry 社区,帮助塑造后端开发更简单、更有效的未来!