Spring Cloud如何实现链路追踪Sleuth

发布时间:2021-12-24 10:42:25 作者:小新
来源:亿速云 阅读:312

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。如果你有任何问题或建议,欢迎在评论区留言。

推荐阅读:
  1. Spring Cloud 微服务开发系列整理
  2. 从架构演进的角度聊聊Spring Cloud都做了些什么?

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

spring cloud sleuth

上一篇:IKEA.com本地文件包含漏洞以及PDF解析的巧妙利用是怎样的

下一篇:linux中如何删除用户组

相关阅读

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

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