分布式追踪介绍

2025年1月11日 | 阅读 7 分钟

分布式追踪

分布式追踪是一种用于监控分析应用程序的技术,特别是那些使用微服务架构构建的应用程序。它也被称为分布式请求追踪。开发人员使用分布式追踪来调试优化代码。

分布式追踪提供了一个地方,我们可以看到“一个特定请求发生了什么?”这一点很重要,因为微服务中涉及各种各样的组件。

如果我们想解决或调试一个问题,我们需要一个中心化的服务器。因此,“分布式追踪”这个术语应运而生。

在本节中,我们将使用Spring Cloud SleuthZipkin。Spring Cloud Sleuth为我们发出的每个请求分配一个唯一ID。我们可以根据唯一ID跨所有组件追踪所有请求。

Spring Cloud Sleuth

Spring Cloud Sleuth是一个Spring Cloud库,它通过在适当的HTTP请求头中添加tracespan ID来跟踪后续微服务的进度。Sleuth库基于MDC(Mapped Diagnostic Context)概念,我们可以轻松地提取值,放入上下文,并在日志中显示它们。

Zipkin

Zipkin是一个开源的、基于Java的分布式追踪系统。它有一个管理控制台,提供了一种机制来发送、接收、存储可视化后续服务的追踪详情。

借助Zipkin服务器,我们可以将所有组件的日志放入MQ(RabbitMQ)中。我们将日志发送到Zipkin服务器进行合并。完成这些之后,我们可以监控不同的请求。我们还可以找出特定请求发生了什么?

使用Spring Cloud Sleuth实现分布式追踪

在此步骤中,我们将为所有微服务添加Spring Cloud Sleuth。它会为所有请求添加一个唯一的ID。它用于生成和附加trace IDspan ID到日志中,以便工具(Zipkin)可以使用这些ID。

Introduction to Distributed Tracing

Spring Cloud Sleuth令牌包含以下组件:

  • 应用程序名称:properties文件中定义的应用程序名称。
  • Trace ID:Sleuth添加Trace ID。对于给定的请求,它在所有服务中保持不变。
  • Span ID:Sleuth也添加Span ID。它在单个工作单元中保持不变,但对于给定的请求,在不同的服务中是不同的。
  • Zipkin导出标志:它表示一个布尔值。它可以是true

下图显示了Spring Cloud Sleuth令牌。

Introduction to Distributed Tracing

让我们在我们的项目中实现Spring Cloud Sleuth

步骤1:选择项目netflix-zuul-api-gateway-server

步骤2:打开pom.xml并添加Sleuth依赖。

现在我们需要追踪所有请求。如果我们想追踪所有请求,我们需要创建ALWAYS_SAMPLE。我们可以使用Bean创建一个Sampler。

Sampler

分布式追踪可能会产生大量数据,因此采样在分布式追踪中很重要。Spring Cloud Sleuth提供了一个Sampler策略。借助Sampler,我们可以实现提供算法控制的采样算法。默认情况下,我们得到一个在span(correlation:是单个操作)已经激活时持续执行追踪的程序。

但是新创建的span总是被标记为non-exportable。如果所有应用程序都与Sampler一起运行,我们可以在日志中看到追踪(由span组成的端到端延迟图),而不是在任何远程位置。默认情况下,Spring Cloud Sleuth将所有span设置为non-exportable

当我们导出span数据到ZipkinSpring Cloud Stream时,Spring Cloud Sleuth提供了AlwaysSampler类,它会将所有内容导出到Zipkin。它还提供了一个PercentageBasedSampler类,它对固定比例的span进行采样。

请记住:如果您使用的是Spring 2.0.0或更高版本,请使用以下Sampler。我们使用了相同的Sampler,因为我们使用的是Spring版本2.2.1

步骤3:打开NetflixZuulApiGatewayServerApplication.java文件并定义一个Bean

NetflixZuulApiGatewayServerApplication.java

在上面的代码中,我们为Zuul API Gateway服务器添加了Spring Cloud Sleuth。

现在我们也需要在currency-exchange-servicecurrency-conversion-service中定义Bean。

步骤4:打开currency-exchange-servicepom.xml并添加Sleuth依赖。

步骤5:打开CurrencyExchangeServiceApplication.java文件并定义一个Bean

CurrencyExchangeServiceApplication.java

步骤6:同样,打开currency-conversion-servicepom.xml并添加Sleuth依赖。

步骤7:打开CurrencyConversionServiceApplication.java文件并定义一个Bean

CurrencyConversionServiceApplication.java

现在我们有了三个连接到Spring Cloud Sleuth的应用程序。

步骤8:按以下顺序启动应用程序

netflix-eureka-naming-server

  • 在浏览器中打开并访问URL https://:8761。它将返回Eureka界面,如下图所示。
Introduction to Distributed Tracing

currency-exchange-service(端口8000)

currency-conversion-service

netflix-zuul-api-gateway-server

请记住:启动每个服务后,刷新Eureka服务器

它显示了当前注册到Eureka服务器的所有实例。

Introduction to Distributed Tracing

步骤9:打开CurrencyExchangeController.java文件并在其中添加一个logger

CurrencyExchangeController.java

同样,我们将在CurrencyConversionController中添加logger。

步骤10:打开CurrencyConversionController.java文件并在其中添加一个logger

CurrencyConversionController.java

步骤12:执行请求 https://:8100/currency-converter-feign/from/EUR/to/INR/quantity/100。它返回以下响应,如下图所示。

Introduction to Distributed Tracing

让我们在控制台中查看currency-conversion-service的日志。currency-conversion-service显示以下日志:

Introduction to Distributed Tracing

我们也可以看到currency-exchange-service的日志。currency-exchange-service显示以下日志:

Introduction to Distributed Tracing

同样,我们可以看到netflix-zuul-api-gateway-server的日志。

Introduction to Distributed Tracing

让我们仔细看看上面不同服务的三个日志。我们发现所有三个服务都有相同的trace ID (533f8d3966d8f4e7)

Spring Cloud Sleuth为请求分配一个trace ID。我们可以使用此ID跨多个组件追踪请求。但是有一个问题是,这个日志分布在多个地方。我们使用Zipkin来解决这个问题。借助Zipkin,我们可以将日志集中在一个地方。

使用 Zipkin 进行分布式追踪

我们在currency-conversion-service、currency-exchange-service和netflix-zuul-api-gateway-server中安装了Spring Cloud Sleuth依赖。我们已经看到,每个请求都被分配了一个唯一的ID。我们使用这些ID来追踪这些多个服务的日志中的请求。

然而,我们在追踪过程中遇到挑战。如果我们想追踪一个请求,就必须检查单个应用程序的日志。这个问题的解决方案称为集中式日志

我们需要集中所有微服务的日志。我们可以通过Spring Cloud Sleuth分配的ID进行搜索。在集中式位置,我们将能够搜索并找出特定请求发生了什么。

以下是集中式日志解决方案:

  • ELK Stack (Elastic Search)
  • Kibana
  • Zipkin
Introduction to Distributed Tracing

在这个分布式追踪中,我们将使用Zipkin分布式追踪服务器。它为我们提供了所有微服务的统一视图。我们从各个微服务获取所有日志消息。Zipkin服务器收集日志消息。所有微服务将日志消息放在一个名为RabbitMQ的队列中,Zipkin从RabbitMQ中拾取这些日志消息。Zipkin追踪服务器连接到数据库。

在我们的例子中,我们使用内存数据库。我们将从数据库中提取日志消息。下一步,我们将安装RabbitMQ。