分布式跟踪、开放式跟踪和 Elastic APM

微服务的世界

企业越来越多地采用微服务架构。他们每天都在开发和部署更多的微服务。通常,这些服务是用不同的编程语言开发的,部署到不同的运行时容器中,并由不同的团队和组织管理。像推特这样的大企业可以拥有成千上万的微服务,所有这些都在一起工作以实现他们的商业目标。正如他们在这篇推特博客文章中讨论的,了解不同服务拓扑的运行状况和性能对于他们能够快速确定问题的根本原因以及提高推特的整体可靠性和效率是极其重要的。

这是分布式跟踪真正能提供帮助的地方。分布式跟踪有助于解决微服务面临的两个基本挑战:

  1. 跟踪延迟
    一个用户请求或事务可以在不同的运行时环境中通过许多不同的服务。理解每个服务对于特定请求的延迟对于理解整个系统的整体性能特征至关重要,并为可能的改进提供有价值的见解。
  2. 根本原因分析
    对于建立在大型微服务生态系统之上的应用程序来说,根本原因分析甚至更具挑战性。任何服务在任何时候都可能出错。分布式跟踪在调试这样一个系统中的问题时至关重要。

退一步说,跟踪只是可观察性的三大支柱-记录、指标和跟踪中的一部分。正如我们将简要讨论的,Elastic Stack 是所有三个可观察性支柱的统一平台。当日志、指标和 APM 数据存储在同一个存储库中,一起进行分析和关联时,您将获得对业务应用程序和系统最丰富的上下文洞察。在本篇博客中,我们将只关注跟踪方面。

Elastic APM 的分布式跟踪

Elastic APM 是建立在 Elastic Stack 上的应用性能监控系统。它允许您实时监控软件服务和应用程序,收集有关传入请求、数据库查询、缓存调用、外部 HTTP 请求等响应时间的详细性能信息。Elastic APM 代理提供丰富的开箱即用的自动检测(例如定时数据库查询等)。获得支持的框架和技术。您也可以出于自定义目的使用自定义仪器。这使得快速查明和修复性能问题变得更加容易。

Elastic APM 支持分布式跟踪,并且兼容开放式跟踪。它使您能够在一个视图中分析整个微服务体系结构的性能。Elastic APM 通过跟踪所有请求来实现这一点,从最初的网络请求到前端服务,再到对后端服务的查询。这使得在整个应用程序中查找可能的瓶颈变得更加容易和快速。APM 用户界面中的时间线可视化显示了跟踪中连接的单个服务的所有事务的瀑布视图:

Elastic Stack 也是日志聚合和指标分析的绝佳平台。将日志、指标和 APM 跟踪都存储在 Elasticsearch 中并有编制索引,这是一种超级强大的功能。能够快速关联基础架构指标、日志和跟踪等数据源使您能够更快地调试根本原因。在 APM 用户界面中,查看跟踪时,如果还收集了主机或容器指标和日志,您可以通过单击操作菜单快速跳转到这些指标和日志。

如果每个人都使用 Elastic APM 来测量他们的应用和服务,那就太好了。然而,Elastic APM 并不是当今唯一可用的分布式跟踪解决方案。还有其他流行的开源跟踪器,比如 Zipkin 和 Jaeger。像多语种编程和多语种持久性这样的概念在微服务领域是众所周知和被广泛接受的。类似地,“多语种跟踪”将会更加普遍。由于微服务的独立性和解耦性,负责不同服务的人可能会使用不同的跟踪系统。

开发者面临的挑战

有了许多不同的跟踪系统,开发人员面临着真正的挑战。一天结束的时候,跟踪者生活在应用程序代码中。一些常见的挑战是:

  1. 使用哪个跟踪系统?
  2. 如果我想改变我的跟踪器呢?我不想改变我的全部源代码。
  3. 我如何处理可能使用不同跟踪程序的共享库?
  4. 如果我的第三方服务使用不同的跟踪程序呢?

毫不奇怪,我们需要标准化来解决这些问题。在讨论标准化的现状之前,让我们退一步,从整体的角度从架构的角度来看分布式跟踪,并理解实现分布式跟踪“涅槃”需要什么。

分布式跟踪的架构组件

现代软件系统可以分解成几个高级组件,通常由不同的组织设计和开发,并在不同的运行环境中运行。

  • 您自己的应用程序代码和服务
  • 共享图书馆和服务
  • 外部服务

为了通过分布式跟踪以整体和集成的方式监控这样一个系统,我们需要四个架构组件:

  1. 标准化分布式跟踪 API。标准化独立于供应商的跟踪 API 允许开发人员以标准化的方式测量他们的代码,而不管他们在运行时后期可能选择使用什么样的跟踪程序。这是迈向任何目标的第一步。
  2. 标准化跟踪上下文定义和传播。要让跟踪从一个运行时跨越到另一个运行时,跟踪上下文必须被双方理解,并且必须有一种传播该上下文的标准方式。至少,上下文携带一个跟踪 ID。
  3. 标准化跟踪数据定义。为了让一个跟踪器的跟踪数据被另一个跟踪器理解和使用,必须有一个标准化的和可扩展的格式。
  4. 互操作跟踪程序。最后,为了实现 100% 的运行时兼容性,不同的跟踪程序必须为它们提供以开放方式从其他跟踪程序导出和导入跟踪数据的机制。理想情况下,由 Jaeger 这样的跟踪程序检测的共享库或服务应该能够通过 Jaeger代 理通过配置更改将它的跟踪数据直接发送到 Elastic APM 或另一个跟踪程序。

现在,关于开放式跟踪。

开放式跟踪规范

开放式跟踪规范为分布式跟踪定义了一个开放的、独立于供应商的 API。它允许用户随时切换开放式跟踪实现者,从而避免供应商锁定。它还使框架和共享库的开发人员能够以标准的方式提供开箱即用的跟踪功能,从而能够更好地洞察框架和库。优步和 Yelp 等网络规模的公司正在使用开放式跟踪来更深入地了解他们高度分布式和动态的应用程序。

开放式跟踪数据模型

开放式跟踪的基本概念和基本的数据模型来自谷歌的 Dapper 论文。关键概念包括跟踪和跨度。

  1. 跟踪表示事务在分布式系统中移动。它可以被认为是跨度的有向无环图。
  2. 跨度是表示具有名称、开始时间和持续时间的逻辑工作单位。跨度可以嵌套和排序以建立关系模型。跨度接受键:值标签以及附加到特定跨度实例的细粒度、时间戳、结构化日志。
  3. 跟踪上下文是分布式事务附带的跟踪信息,包括它何时通过网络或消息总线将服务传递给服务。上下文包含跟踪标识符、跨度标识符以及跟踪系统需要传播到下游服务的任何其他数据。

这一切是如何组织的?

理想情况下,通过标准化,跟踪来自不同组织开发和运行的自定义应用程序代码、共享库和共享服务的信息是可交换的和运行时兼容的,不管这些组件选择使用哪种跟踪器。

然而,开放式跟踪只解决了我们之前讨论的四个架构组件中的第一个。那么,我们现在与其他组件的关系如何,我们的未来会怎样?

我们现在发展到什么程度了?

正如我们所讨论的,开放式跟踪为不同的跟踪者定义了一组标准的跟踪 API 来实现,这是一个很好的开始,也非常令人鼓舞。然而,我们仍然需要跟踪上下文标准化和跟踪数据标准化,以便它们能够相互兼容和交换。

  1. 开放式跟踪 API 提供了一组标准的 API。这几乎是我们目前唯一的标准化。规范也有局限性。例如,它没有涵盖所有的编程语言。然而,这是一个了不起的努力,并获得了巨大的牵引力。
  2. 还没有标准化的跟踪上下文定义W3C 分布式跟踪工作组正在标准化跟踪上下文定义 W3C跟踪上下文规范。该规范定义了分布式系统中上下文和事件关联的统一方法,并将支持跨不同监控工具的分布式应用程序中的端到端事务跟踪。Elastic APM 支持 W3C 跟踪上下文工作组标准化分布式跟踪的 HTTP 头格式的努力。我们的代理实现严格遵循跟踪上下文草案规范,我们打算完全支持最终规范。

    作为当今跟踪上下文不兼容的一个例子,这里有一个 Elastic APM 和 Jaeger 用于跟踪标识的 HTTP 头的例子。如您所见,ID 的名称和编码都是不同的。当使用不同的跟踪头时,当它们跨越各自跟踪工具的边界时,跟踪将中断。

    Jaeger:
    uber-trace-id:118c6c15301b9b3b3:56e66177e6e55a91:18c6c15301b9b3b3:1

    Elastic APM:
    elastic-apm-traceparent:00-f109f092a7d869fb4615784bacefcfd7-5bf936f4fcde3af0-01

    除了定义本身,还有其他挑战。例如,并不是所有的超文本传输协议报头都是由服务基础设施和路由器等自动转发的。每当头被丢弃时,跟踪就会中断。
  3. 还没有标准化的跟踪数据定义。正如 W3C 分布式跟踪工作组所指出的,跟踪互操作性的第二个难题是“一种标准化的和可扩展的格式,用于跨工具共享跟踪数据——完整的跟踪或跟踪片段,以供进一步解释”。可以想象,有许多开源和商业参与者参与,就标准格式达成一致不是一件容易的事情。希望我们能很快到达那里。
  4. 跟踪程序与运行时不兼容。由于我们上面讨论的所有内容,加上让他们的系统开放并与世界其他地方兼容的混合动机,在现在的运行时,跟踪程序是完全不兼容的。我可以自信地说,在可预见的将来,这可能会是这样。

如今 Elastic APM 如何与其他跟踪器配合使用

即使我们现在还没有接近跟踪程序之间的 100% 兼容性,也没有必要气馁。 Elastic Stack 仍然可以用几种不同的方式与其他跟踪器一起工作。

  1. Elasticsearch作为可扩展后端数据存储用于其他跟踪程序。

    不出所料,Elasticsearch 由于其巨大的可扩展性和丰富的分析能力,已经被用作其他跟踪者(如 Zipkin 和 Jaeger)的后端数据存储。将 Zipkin 或 Jaeger 跟踪数据传送到 Elasticsearch 对他们来说都是一个简单的配置。一旦跟踪数据进入 Elasticsearch,您就可以使用 Kibana 强大的分析和可视化功能来分析您的跟踪信息,并创建引人注目的可视化效果,从而深入了解您的应用程序性能。
  2. Elastic 开放式跟踪桥

    Elastic APM 开放式跟踪桥允许您使用开放式跟踪 API 创建 Elastic APM 事务和跨度。换句话说,它将对开放式跟踪 API 的调用转换成 Elastic APM,从而允许重用现有的工具。例如,Jaeger 完成的现有仪器可以简单地用 Elastic APM 替换,只需修改几行代码。

    Jaeger 的原始仪器:

    import io.opentracing.Scope;
    import io.opentracing.Tracer;
    import io.jaegertracing.Configuration;
    import io.jaegertracing.internal.JaegerTracer;
    ...
    private void sayHello(String helloTo) {
        Configuration config = ...
        Tracer tracer = config.getTracer();
        try (Scope scope = tracer.buildSpan("say-hello").startActive(true)) {
            scope.span().setTag("hello-to", helloTo);
        }
        ...
    }
        
    用 Elastic 开放式跟踪桥替换 Jaeger:

    import io.opentracing.Scope;
    import io.opentracing.Tracer;
    import co.elastic.apm.opentracing.ElasticApmTracer;
    ...
    private void sayHello(String helloTo) {
        Tracer tracer = new ElasticApmTracer();
        try (Scope scope = tracer.buildSpan("say-hello").startActive(true)) {
            scope.span().setTag("hello-to", helloTo);
        }
        ...
    }
        


    通过这个简单的更改,跟踪数据将轻松地流入 Elastic APM,而无需修改其他跟踪代码。这就是开放式跟踪的力量!

Elastic APM 真实用户监控

而在讨论跟踪和上下文传播等时,我们主要关注后端服务。,在浏览器的客户端启动跟踪非常有价值。这样做时,当用户点击浏览器中的某个东西时,您会得到跟踪信息。该跟踪信息从性能方面代表了应用程序的“真实用户体验”。不幸的是,现在没有标准的方式来转发这些信息。W3C 小组确实打算将来把跟踪上下文一直扩展到浏览器。

Elastic APM 实际用户监控(RUM)现在正好提供了这一功能。RUM JS 代理监控客户端应用程序中的真实用户体验。您将能够测量“首字节时间”、“优势活动”和“完成时间”等指标,帮助您发现客户端应用程序中的性能问题以及与服务器端应用程序延迟相关的问题。我们的 RUM JS 代理与框架无关,这意味着它可以与任何基于 JavaScript 的前端应用程序一起使用。

<p?</p?

结论

希望本篇能帮助你更好地理解分布式跟踪的前景,并澄清一些关于我们现在使用开放式跟踪的困惑。让我们简单总结一下:

  1. 分布式跟踪为微服务提供了无价的性能洞察。
  2. 开放式跟踪是行业走向分布式跟踪标准化的第一步。要完全兼容,我们还有很长的路要走。
  3. Elastic APM 符合开放式跟踪标准。
  4. Elastic 开放式跟踪桥允许仪器复用。
  5. Elastic Stack 是一个很好的可扩展的长期存储,适用于其他跟踪程序,如 Zipkin 和 Jaeger,即使现在没有完全的运行时兼容性。
  6. Elastic 为跟踪数据提供了丰富的分析。将 Zipkin 或 Jaeger 跟踪数据传送到 Elasticsearch 是一个简单的配置。
  7. Elastic APM 真实用户监控(RUM)监控客户端应用程序中的真实用户体验。
  8. 总而言之,Elastic 是一个可大规模扩展、功能丰富且统一的分析平台,适用于可观察性的三大支柱 - 日志记录、指标和跟踪。

如往常一样,如果您想展开讨论或有任何问题,请在 Elastic APM 论坛上留言。跟踪愉快!