微服务分布式跟踪工具Brave简介

在微服务架构非常流行的现代软件开发中,跟踪和分析跨各种服务的请求流的能力至关重要。因此,分布式跟踪成为一种重要工具,可以深入了解我们系统的性能和行为。

在本教程中,我们将介绍Brave,它是 Java 生态系统中流行的分布式跟踪工具库。

什么是分布式追踪
分布式跟踪是一种用于监视和排除由互连服务组成的复杂分布式系统的方法。在此类系统中,请求可能会遍历多个服务,每个服务负责执行特定任务。因此,如果不使用一些专用工具,跟踪请求的过程可能会变得具有挑战性。

在探索分布式跟踪之前,我们必须定义两个关键概念:跟踪和跨度。跟踪表示外部请求并由一组跨度组成。一个span代表一个操作;其关键属性是操作名称、开始时间和结束时间。一个跨度可以有一个或多个表示嵌套操作的子跨度。

现在,让我们探讨分布式跟踪的关键组件:检测库和分布式跟踪服务器。每个服务使用的检测库的主要目的是生成和传播跟踪数据。这涉及捕获服务内的操作细节,例如处理传入请求、对其他服务或数据库进行出站调用以及处理数据。

另一方面,分布式跟踪服务器代表跟踪数据管理的中央枢纽。它提供用于从仪器库接收跟踪数据、聚合和存储数据的 API,并提供用于分析、监控和故障排除的工具。


Zipkin是什么?
Zipkin是一个领先的开源分布式追踪系统,最初由 Twitter 开发。它旨在帮助收集解决微服务架构中的延迟问题所需的数据。它从仪表化服务收集数据,然后提供该数据的详细视图。

Zipkin 包含四个主要组件,我们将在以下小节中详细介绍每个组件。

收集器Collector
当检测服务生成跟踪数据时,需要收集和处理。因此,收集器负责接收和验证 Zipkin 接收到的痕迹。一旦痕迹经过验证,它们就会被存储以供以后检索和分析。收集器可以通过HTTP或AMQP接收数据,使其灵活且适合各种系统架构。

贮存器
Zipkin 最初是为了使用Cassandra存储数据而构建的 ,因为它具有高度可扩展性、灵活性,并且在 Twitter 中得到广泛使用。然而,Zipkin 已更新为更具可配置性,支持其他存储选项,例如ElasticSearch、MySQL,甚至内存存储。

API
数据存储后,Zipkin 会通过 RESTful 界面提供直观的数据提取方法。该接口使我们能够根据需要轻松定位和检索痕迹。此外,该 API 还充当 Zipkin Web UI 的支柱,而 Zipkin Web UI 是其主要数据源。

网页用户界面
Zipkin 提供的图形用户界面 (GUI) 代表了一种可视化可访问的方法,用于根据服务、时间和注释检查跟踪。此外,它通过允许我们深入研究特定的跟踪来促进详细的分析,这使得它对于解决涉及分布式事务的复杂问题特别有价值。

什么是Brave
Brave 是一个分布式跟踪仪器库。它拦截生产请求、收集计时数据并传播跟踪上下文。其主要目标是促进分布式系统内计时数据的关联,从而能够有效地解决延迟问题。

尽管 Brave 通常将跟踪数据发送到 Zipkin 服务器,但它通过第三方插件提供了与Amazon X-Ray等其他服务集成的灵活性。

Brave 提供与 JRE6 及更高版本兼容的无依赖跟踪器库。它提供了一个重要的 API,用于计时操作并用描述性属性标记它们。该库还包含解析X-B3-TraceId标头的代码  ,进一步丰富了其功能。

虽然直接跟踪代码实现通常是不必要的,但用户可以利用Brave 和 Zipkin 提供的现有工具。值得注意的是,用于常见跟踪场景(如 JDBC、Servlet 和 Spring)的库随时可用,经过精心测试和基准测试。

对于那些处理遗留应用程序的人来说,Spring XML 配置提供了无缝的跟踪设置,无需自定义代码。

用户还可能寻求将跟踪 ID 集成到日志文件中或修改线程本地行为。在这种情况下,Brave 提供的上下文库可以与 SLF4J 等工具无缝集成。

如何使用
接下来,让我们构建一个简单的 Java 和 Spring Boot 应用程序,并将其与 Brave 和 Zipkin 集成。

Zipkin 超薄设置
首先,我们需要运行一个 Zipkin 服务器。为此,我们将使用 Zipkin Slim,这是 Zipkin 的精简版,它更小,启动速度更快。它支持内存和 Elasticsearch 存储,但不支持通过 Kafka 或 RabbitMQ 进行消息传递。

Zipkin 的官方存储库中记录了多种使用方法。此外,运行 Zipkin 服务器的更多方法可以在我们关于使用 Zipkin 进行跟踪服务的文章中找到。

为简单起见,我们假设本地计算机上已经安装了Docker,并使用以下命令运行它:

docker run -d -p 9411:9411 openzipkin/zipkin-slim

现在,通过访问http://localhost:9411/zipkin/,我们可以可视化 Zipkin Web UI。

项目设置
我们将从一个带有brave、zipkin-reporter、zipkin-sender-okhttp3和zipkin-reporter-brave依赖项的空Spring Boot项目开始:

<dependency>
    <groupId>io.zipkin.brave</groupId>
    <artifactId>brave</artifactId>
    <version>6.0.2</version>
</dependency>
<dependency>
    <groupId>io.zipkin.reporter2</groupId>
    <artifactId>zipkin-reporter</artifactId>
    <version>3.3.0</version>
</dependency>
<dependency>
    <groupId>io.zipkin.reporter2</groupId>
    <artifactId>zipkin-sender-okhttp3</artifactId>
    <version>3.3.0</version>
</dependency>
<dependency>
    <groupId>io.zipkin.reporter2</groupId>
    <artifactId>zipkin-reporter-brave</artifactId>
    <version>3.3.0</version>
</dependency>

继续,我们需要一个配置类来实例化Tracer bean 以便稍后使用它:

@Configuration
public class TracingConfiguration {
    @Bean
    BytesMessageSender sender() {
        return OkHttpSender.create("http://127.0.0.1:9411/api/v2/spans");
    }
    @Bean
    AsyncZipkinSpanHandler zipkinSpanHandler(BytesMessageSender sender) {
        return AsyncZipkinSpanHandler.create(sender);
    }
    @Bean
    public Tracing tracing(AsyncZipkinSpanHandler zipkinSpanHandler) {
        return Tracing.newBuilder()
          .localServiceName(
"Dummy Service")
          .addSpanHandler(zipkinSpanHandler)
          .build();
    }
    @Bean
    public Tracer tracer(Tracing tracing) {
        return tracing.tracer();
    }
}

现在,我们可以将 Tracer 直接注入到我们的 bean 中。为了进行演示,我们将创建一个虚拟服务,该服务在初始化后将向 Zipkin 发送跟踪:

@Service
public class TracingService {
    private final Tracer tracer;
    public TracingService(Tracer tracer) {
        this.tracer = tracer;
    }
    @PostConstruct
    private void postConstruct() {
        Span span = tracer.nextSpan().name("Hello from Service").start();
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } finally {
            span.finish();
        }
    }
}

如果我们运行我们的应用程序并检查 Zipkin Web UI,我们应该能够看到我们的跟踪,仅包含一个跨度,大约需要 2 秒:


请注意,此示例仅简单配置了跟踪。当处理更复杂的场景时,建议使用Spring Cloud Sleuth。

此外,brave-example存储库还描述了跟踪简单 Web 应用程序的替代方法。

结论
正如我们在整篇文章中了解到的,Brave 帮助我们有效地监控我们的应用程序。 Brave 简化了检测流程,并通过与 Zipkin 的无缝集成证明了分布式系统中的宝贵资产。