温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Spring Cloud如何实现链路追踪Sleuth

发布时间:2021-12-24 10:42:25 来源:亿速云 阅读:329 作者:小新 栏目:大数据

Spring Cloud如何实现链路追踪Sleuth

在现代微服务架构中,随着服务数量的增加,系统的复杂性也随之增加。一个请求可能会经过多个服务,每个服务都可能调用其他服务。这种情况下,如何追踪一个请求的完整路径,以及每个服务的调用情况,成为了一个非常重要的问题。Spring Cloud Sleuth 就是为了解决这个问题而生的。

什么是Spring Cloud Sleuth?

Spring Cloud Sleuth 是 Spring Cloud 生态系统中的一个组件,用于在分布式系统中实现链路追踪。它通过为每个请求生成唯一的追踪ID(Trace ID)和跨度ID(Span ID),来追踪请求在系统中的流转路径。Sleuth 可以与 Zipkin 等分布式追踪系统集成,将追踪数据发送到这些系统中进行存储和展示。

Sleuth 的核心概念

在了解如何使用 Sleuth 之前,我们需要先了解一些核心概念:

  1. Trace ID: 一个请求的唯一标识符,通常是一个64位的数字。一个请求在系统中流转时,Trace ID 保持不变。
  2. Span ID: 一个请求在某个服务中的唯一标识符,通常也是一个64位的数字。一个请求在系统中流转时,每个服务都会生成一个新的 Span ID。
  3. Parent Span ID: 当前 Span 的父 Span 的 ID。如果一个服务调用了另一个服务,那么被调用服务的 Span 的 Parent Span ID 就是调用服务的 Span ID。
  4. Span: 一个 Span 代表一个请求在某个服务中的处理过程。它包含了开始时间、结束时间、标签、日志等信息。
  5. Annotation: 用于记录某个事件的时间戳。例如,一个请求的开始时间、结束时间等。

如何在Spring Cloud中使用Sleuth?

1. 添加依赖

首先,我们需要在项目中添加 Sleuth 的依赖。如果你使用的是 Maven,可以在 pom.xml 中添加以下依赖:

<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-sleuth</artifactId> </dependency> 

如果你使用的是 Gradle,可以在 build.gradle 中添加以下依赖:

implementation 'org.springframework.cloud:spring-cloud-starter-sleuth' 

2. 配置Sleuth

Sleuth 的配置非常简单,通常情况下不需要进行额外的配置。Sleuth 会自动为每个请求生成 Trace ID 和 Span ID,并将这些信息添加到日志中。

如果你需要自定义 Sleuth 的行为,可以在 application.ymlapplication.properties 中进行配置。例如,你可以配置 Sleuth 的采样率:

spring: sleuth: sampler: probability: 1.0 

probability 表示采样率,取值范围是 0.0 到 1.0。1.0 表示对所有请求进行采样,0.5 表示对 50% 的请求进行采样。

3. 查看日志

Sleuth 会自动将 Trace ID 和 Span ID 添加到日志中。你可以在日志中看到类似以下的输出:

2023-10-01 12:00:00.000 INFO [service-name,trace-id,span-id,true] 12345 --- [nio-8080-exec-1] c.e.s.ServiceController : Processing request 

其中,[service-name,trace-id,span-id,true] 就是 Sleuth 添加的追踪信息。service-name 是当前服务的名称,trace-id 是请求的 Trace ID,span-id 是当前 Span 的 ID,true 表示这是一个可导出的 Span。

4. 集成Zipkin

Sleuth 可以与 Zipkin 集成,将追踪数据发送到 Zipkin 中进行存储和展示。要集成 Zipkin,首先需要添加 Zipkin 的依赖:

<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zipkin</artifactId> </dependency> 

然后,在 application.yml 中配置 Zipkin 的地址:

spring: zipkin: base-url: http://localhost:9411 

配置完成后,Sleuth 会自动将追踪数据发送到 Zipkin 中。你可以在 Zipkin 的 UI 中查看请求的完整路径和每个服务的调用情况。

5. 手动创建Span

在某些情况下,你可能需要手动创建 Span。例如,你希望在某个方法中记录一些自定义的追踪信息。你可以使用 Tracer 接口来手动创建 Span:

import org.springframework.cloud.sleuth.Tracer; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class MyService { @Autowired private Tracer tracer; public void doSomething() { Span newSpan = tracer.nextSpan().name("my-custom-span").start(); try (Tracer.SpanInScope ws = tracer.withSpan(newSpan.start())) { // 在这里执行你的业务逻辑 } finally { newSpan.end(); } } } 

在这个例子中,我们手动创建了一个名为 my-custom-span 的 Span,并在其中执行了一些业务逻辑。tracer.withSpan(newSpan.start()) 用于将当前 Span 设置为新的 Span,并在 try 块结束后自动结束 Span。

6. 添加自定义标签

你还可以为 Span 添加自定义标签,以便在 Zipkin 中更好地展示追踪信息。你可以使用 Spantag 方法来添加标签:

import org.springframework.cloud.sleuth.Span; import org.springframework.cloud.sleuth.Tracer; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class MyService { @Autowired private Tracer tracer; public void doSomething() { Span newSpan = tracer.nextSpan().name("my-custom-span").start(); try (Tracer.SpanInScope ws = tracer.withSpan(newSpan.start())) { newSpan.tag("custom-tag", "custom-value"); // 在这里执行你的业务逻辑 } finally { newSpan.end(); } } } 

在这个例子中,我们为 Span 添加了一个名为 custom-tag 的标签,并将其值设置为 custom-value

7. 异步调用中的追踪

在微服务架构中,异步调用是非常常见的。Sleuth 也支持在异步调用中进行追踪。你只需要使用 Tracerwrap 方法来包装异步任务:

import org.springframework.cloud.sleuth.Tracer; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.concurrent.CompletableFuture; @Service public class MyService { @Autowired private Tracer tracer; public CompletableFuture<Void> doSomethingAsync() { return CompletableFuture.runAsync(tracer.wrap(() -> { // 在这里执行你的异步任务 })); } } 

在这个例子中,我们使用 tracer.wrap 方法包装了一个异步任务。Sleuth 会自动为这个异步任务生成一个新的 Span,并将其与当前 Span 关联起来。

8. 跨服务调用中的追踪

在微服务架构中,服务之间的调用是非常频繁的。Sleuth 会自动为跨服务调用生成新的 Span,并将其与当前 Span 关联起来。你只需要确保在跨服务调用时传递 Trace ID 和 Span ID。

如果你使用的是 RestTemplate 进行 HTTP 调用,Sleuth 会自动为你处理这些细节:

import org.springframework.web.client.RestTemplate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class MyService { @Autowired private RestTemplate restTemplate; public void callAnotherService() { String response = restTemplate.getForObject("http://another-service/api", String.class); // 处理响应 } } 

如果你使用的是 Feign 客户端,Sleuth 也会自动为你处理这些细节:

import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; @FeignClient(name = "another-service") public interface AnotherServiceClient { @GetMapping("/api") String callApi(); } 

9. 自定义Span名称

默认情况下,Sleuth 会使用 HTTP 请求的路径作为 Span 的名称。如果你希望自定义 Span 的名称,可以使用 @SpanName 注解:

import org.springframework.cloud.sleuth.annotation.SpanName; import org.springframework.stereotype.Service; @Service public class MyService { @SpanName("my-custom-span-name") public void doSomething() { // 在这里执行你的业务逻辑 } } 

在这个例子中,我们使用 @SpanName 注解将 Span 的名称设置为 my-custom-span-name

10. 自定义Span过滤器

在某些情况下,你可能希望过滤掉某些 Span。例如,你可能不希望记录某些健康检查请求的 Span。你可以通过实现 SpanFilter 接口来自定义 Span 过滤器:

import org.springframework.cloud.sleuth.Span; import org.springframework.cloud.sleuth.SpanFilter; import org.springframework.stereotype.Component; @Component public class MySpanFilter implements SpanFilter { @Override public boolean isExportable(Span span) { // 在这里实现你的过滤逻辑 return !span.name().contains("health-check"); } } 

在这个例子中,我们实现了一个 SpanFilter,过滤掉所有名称包含 health-check 的 Span。

总结

Spring Cloud Sleuth 是一个非常强大的工具,可以帮助我们在分布式系统中实现链路追踪。通过为每个请求生成唯一的 Trace ID 和 Span ID,Sleuth 可以追踪请求在系统中的流转路径,并将这些信息记录到日志中。通过与 Zipkin 等分布式追踪系统集成,我们可以更好地理解和分析系统的调用情况。

在实际使用中,Sleuth 的配置和使用非常简单,几乎不需要额外的代码。我们只需要添加依赖,配置采样率,就可以开始使用 Sleuth 进行链路追踪。如果你有更复杂的需求,例如手动创建 Span、添加自定义标签、过滤 Span 等,Sleuth 也提供了丰富的 API 来满足这些需求。

希望这篇文章能帮助你更好地理解和使用 Spring Cloud Sleuth。如果你有任何问题或建议,欢迎在评论区留言。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI