微信登录

分布式链路追踪 - Sleuth - 日志追踪工具

分布式链路追踪 - Sleuth - 日志追踪工具

一、引言

在当今的互联网应用中,分布式系统变得越来越普遍。一个大型的业务系统往往由多个微服务组成,这些微服务相互调用,共同完成复杂的业务逻辑。当系统出现问题时,由于服务之间的调用关系错综复杂,定位问题变得十分困难。分布式链路追踪工具应运而生,它可以帮助我们记录请求在各个服务之间的调用路径和相关信息,从而快速定位问题。Spring Cloud Sleuth 就是这样一款强大的分布式链路追踪工具,它为 Spring 生态系统提供了无缝的集成,能够方便地实现日志追踪。

二、Sleuth 核心概念

1. Trace(追踪)

Trace 代表一个完整的请求调用链,它是由一系列的 Span 组成。每个 Trace 都有一个唯一的 Trace ID,用于标识这个请求调用链。

2. Span(跨度)

Span 是 Trace 中的一个基本工作单元,它表示一次独立的调用。每个 Span 都有一个唯一的 Span ID,同时它还包含了一些元数据,如开始时间、结束时间、调用的服务名等。Span 之间可以有父子关系,形成一个树形结构。

3. Baggage(行李)

Baggage 是一个键值对的集合,它可以在整个 Trace 中传递。Baggage 中的数据可以在不同的 Span 中被访问和修改,常用于传递一些全局的上下文信息。

三、Sleuth 实践演示

1. 项目搭建

我们创建两个 Spring Boot 项目,分别命名为 service-aservice-b,并添加 Sleuth 依赖。

service-apom.xml

  1. <dependencies>
  2. <dependency>
  3. <groupId>org.springframework.boot</groupId>
  4. <artifactId>spring-boot-starter-web</artifactId>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.springframework.cloud</groupId>
  8. <artifactId>spring-cloud-starter-sleuth</artifactId>
  9. </dependency>
  10. </dependencies>

service-bpom.xml

同样添加 spring-boot-starter-webspring-cloud-starter-sleuth 依赖。

2. 代码实现

service-a 的控制器代码

  1. import org.springframework.beans.factory.annotation.Autowired;
  2. import org.springframework.web.bind.annotation.GetMapping;
  3. import org.springframework.web.bind.annotation.RestController;
  4. import org.springframework.web.client.RestTemplate;
  5. @RestController
  6. public class ServiceAController {
  7. @Autowired
  8. private RestTemplate restTemplate;
  9. @GetMapping("/call-service-b")
  10. public String callServiceB() {
  11. String response = restTemplate.getForObject("http://localhost:8081/service-b", String.class);
  12. return "Service A called Service B. Response: " + response;
  13. }
  14. }

service-b 的控制器代码

  1. import org.springframework.web.bind.annotation.GetMapping;
  2. import org.springframework.web.bind.annotation.RestController;
  3. @RestController
  4. public class ServiceBController {
  5. @GetMapping("/service-b")
  6. public String serviceB() {
  7. return "Hello from Service B!";
  8. }
  9. }

3. 配置文件

application.properties 中添加以下配置:

  1. spring.application.name=service-a # 对于 service-a 项目
  2. # spring.application.name=service-b # 对于 service-b 项目
  3. server.port=8080 # 对于 service-a 项目
  4. # server.port=8081 # 对于 service-b 项目

4. 运行项目

分别启动 service-aservice-b 项目,然后访问 http://localhost:8080/call-service-b,在控制台可以看到类似如下的日志:

  1. [service-a,5d3a8a7c6a9d1b2e,5d3a8a7c6a9d1b2e,true] INFO ... - Handling call to /call-service-b
  2. [service-b,5d3a8a7c6a9d1b2e,3f8a9b7c6d8e9f0a,true] INFO ... - Handling call to /service-b

日志中的方括号内的信息分别为:应用名、Trace ID、Span ID、是否采样。可以看到,两个服务的 Trace ID 是相同的,说明它们属于同一个请求调用链。

四、Sleuth 与日志集成

Sleuth 可以与日志框架(如 Logback、Log4j 等)集成,将 Trace ID 和 Span ID 输出到日志中。以 Logback 为例,在 logback-spring.xml 中添加以下配置:

  1. <pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] [%X{X-B3-TraceId:-},%X{X-B3-SpanId:-},%X{X-B3-ParentSpanId:-},%X{X-Span-Export:-}] %-5level %logger{36} - %msg%n</pattern>

这样,日志中就会包含 Trace ID 和 Span ID 信息,方便我们进行追踪。

五、总结

概念 描述
Trace 代表一个完整的请求调用链,有唯一的 Trace ID
Span 是 Trace 中的基本工作单元,有唯一的 Span ID,可形成树形结构
Baggage 键值对集合,可在整个 Trace 中传递全局上下文信息

Spring Cloud Sleuth 是一款非常实用的分布式链路追踪工具,它可以帮助我们轻松地实现日志追踪,快速定位分布式系统中的问题。通过本文的演示,你可以看到 Sleuth 的使用非常简单,只需要添加依赖和少量的配置,就可以在项目中集成日志追踪功能。在实际开发中,我们可以结合其他工具(如 Zipkin)来实现更强大的分布式链路追踪功能。

分布式链路追踪 - Sleuth - 日志追踪工具