OpenTelemetry

介绍

在第一部分中,我们研究了现代系统的可观察性挑战——微服务、可组合架构、事件驱动、共享组件——所有这些好东西都能很好地解决问题。但是他们真的很难支持。我们强调了对正确数据进行检测的重要性,并得出结论,有许多良好的可观察性解决方案,包括开源的和商业的。但他们都以自己的方式做事,极大地降低了我们的灵活性和适应能力——让我们的老对手供应商锁在门外。

在本文中,我们将了解 OpenTelemetry 如何弥合我们的代码和可观察性后端选项之间的差距,从而支持摆脱使用特定于供应商的工具来生成和导出遥测数据。

快速复习

在我们开始之前,让我们从第一部分更新我们的术语:

OpenTelemetry_第1张图片

-仪器 是产生遥测的东西。当我们谈论检测时,我们的意思是向我们的应用程序添加库和/或代码以收集遥测数据,例如日志、指标和跟踪。

-遥测 是对系统行为或内部运作的洞察——系统发出的关于“黑匣子”内发生的事情的数据,通过仪器收集。您可能还会听到这些被称为信号的声音。

供应商中立标准

OpenTelemetry (OTel) 的核心是跨语言遥测的供应商中立标准。您只需要检测您的代码一次,然后可以在您的需求发生变化时轻松更改为其他可观察性后端。

这也意味着您可以坚持使用您选择的后端,同时能够更改您使用的语言 - 所有受支持的语言都将遵守相同的检测 API 规范。

不仅仅是供应商中立的标准

OTel 还提供**完整的端到端实施**,用于生成、发送、收集、处理遥测数据并将其导出到任何支持的可观察性后端。对于当前支持的每种语言,都有核心库、自动检测库和导出器。

核心库

API 是用于检测的基本接口——不会将实际的遥测数据发送到后端。这样做是因为希望检测其代码的第三方库不需要关心消费应用程序如何实现其 OpenTelemetry。

SDK 是提供 API 实现的完整语言库,因此我们可以手动检测我们的代码。这是我们直接拉入应用程序的内容。它没有实现导出器,它们是依赖于 SDK 的独立库。实现 API 的单独库中提供了替代工具。

通常,我们希望通过 OTel 连接到可观察性后端的任何应用程序都将通过对检测库和导出器的依赖来间接依赖这两者。

仪器库

用于许多常见库和框架的即插即用,例如用于 Web 和数据库的库和框架。例如,我们可以为 ASP.NET Core 传入的 Web 请求和传出的 Entity Framework 请求自动生成遥测数据。唯一需要的步骤是添加两个包:

  • OpenTelemetry.Instrumentation.AspNetCore
  • OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore

 并将它们作为服务添加到代码中:

C#
public void ConfigureServices(IServiceCollection services)
{
    services.AddOpenTelemetryTracing((builder) => builder
        .AddAspNetCoreInstrumentation()
        .AddEntityFrameworkCoreInstrumentation()
        // Add your exporter(s) here
    );
}

OTel 项目在每种语言的主存储库中维护关键 OSS 项目的检测和导出程序包,并符合 OTel 规范。对于 .NET,这是open-telemetry/opentelemetry-dotnet。然后可以从姊妹 contrib 存储库中获得许多其他存储库,对于 .NET,该存储库是open-telemetry/opentelemetry-dotnet-contrib。

出口商

导出器是将检测的遥测数据发送到后端的库。这可以通过 OpenTelemetry 协议 (OTLP) 本身 - 这是长期目标* - 或特定于供应商(例如 Jaegar 或 Azure Monitor),其中导出器库将从内存中的 OpenTelemetry 数据转换为使用的格式通过供应商工具。这些类型的出口商的可用性使得计划和执行向 OTLP 的过渡变得更加容易。

*供应商越来越多地为直接进入本地 OTLP 提供全面支持。请参阅此列表 以获取更新。Jaeger 文档现在甚至声明:

引用:

自 2022 年起,不再支持 Jaeger SDK,建议所有用户迁移到 OpenTelemetry。

供应商中立跟踪

在调试分布式系统时,我面临的最大挑战之一是通过所涉及的所有服务获得事务的完整端到端旅程的可见性。

在第 1 部分中,我们介绍了分布式跟踪作为解决此问题的任何可观察性解决方案的关键部分。我们承认,已经有许多开源和商业产品通过在事务中的所有操作之间传播跟踪 ID 以将所有内容联系在一起来做到这一点。

但通常情况下,我们最终会得到一幅不完整的画面,企业只是将其视为一种风险,尽管我们加大了支持力度。造成这种情况的一些常见原因包括:

  • 混合技术堆栈上的服务需要不同的解决方案,而资源限制使我们无法对所有这些服务进行检测
  • 供应商锁定,我们选择的后端不支持我们某些服务的技术堆栈
  • 检测和发送遥测数据的客户和代理是内部构建的,资源限制使我们无法为所有服务技术堆栈维护它们

作为技术堆栈和后端的单一标准,OTel 消除了这些挑战。它带来了一套完整的工具,真正做到了简单的插入,大大减少了所需的资源,并且因为它是一个开放的标准,切换到(或添加)其他后端需要很少的资源。

OpenTelemetry 如何进行跟踪

OTel 使用 **span** 的概念表示跨系统的跟踪中的每个操作。除OTel 规范中定义的其他内容外,每个跨度将包含:

  • 通过系统的当前交易的整个“旅程”的唯一跟踪 ID
  • span 本身的唯一 ID
  • 父跨度的唯一 ID,因此我们可以在可观察性后端重建旅程

每个跨度表示通过系统的整个事务中的单个操作。大多数后端都会以一种您可能熟悉的甘特图方式来代表这些时间。

OpenTelemetry_第2张图片

在这个简化的例子中:

  1. Span A:请求进入服务 A 以获取用户详细信息。这是**根跨度**,当然也是**跨度 B** 的父级。大多数主流 Web 框架将能够自动检测这一点,这意味着它将自动为这个传入请求创建一个跟踪跨度。
  2. pan B:服务 A 调用服务 B 以获取用户的详细信息。我们可以从库中获取它来自动检测 HTTP 调用,或者我们可以手动添加一个跟踪信号“围绕”进行调用的代码。
  3. Span C:服务 B 接收请求。
  4. Span D:在处理请求的代码中,子 span 表示对数据库的 SQL 查询,以获取用户详细信息。
  5. 跨度 E:如果未找到,我们手动检测用于添加用户的信号。
  6. Span F:服务 B 已返回用户详细信息,服务 A 将该数据返回给调用者,这是由我们的 Web 框架自动检测的。

你可能感兴趣的:(java,开发语言)