实现Spring Cloud Sleuth的Trace ID追踪日志实战教程

实现Spring Cloud Sleuth的Trace ID追踪日志

Spring Cloud Sleuth的Trace ID追踪主要用于分布式系统中实现请求链路跟踪,其核心作用包括:

请求链路串联‌:Trace ID在一次服务请求链路中保持并传递,将不同服务的请求跟踪信息串联起来,确保所有服务的日志关联。例如,一个请求从前端A到后端D,Trace ID在各服务中保持一致,形成完整链路。

问题定位‌:通过Trace ID,可以快速定位请求经过的服务单元及顺序,尤其在微服务架构中,帮助快速识别故障服务。例如,若请求在服务C失败,Trace ID可追踪到完整调用路径。

性能分析‌:Trace ID结合Span ID(工作单元ID)统计各服务处理延迟,区分执行时间和网络延迟,优化性能。例如,分析服务调用耗时,识别瓶颈服务。

可视化监控‌:与Zipkin等工具集成后,Trace ID生成的链路数据可可视化展示,提供服务拓扑图和性能指标。例如,通过Zipkin UI查看调用关系和响应时间。

日志关联‌:在日志系统中,Trace ID作为关键字段,通过ELK等工具可快速检索同一请求的全链路日志。例如,通过Trace ID提取所有服务的日志片段,形成完整日志链路。

综上,Trace ID是分布式系统中实现链路追踪、问题定位和性能优化的核心机制。

添加依赖

在项目的pom.xml文件中添加Spring Cloud Sleuth依赖。确保版本与Spring Boot和Spring Cloud兼容。

xml 复制代码
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>

如果使用日志聚合工具如Zipkin,可以添加以下依赖:

xml 复制代码
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-sleuth-zipkin</artifactId>
</dependency>

配置日志格式

application.propertiesapplication.yml中配置日志格式以显示Trace ID和Span ID。

properties 复制代码
logging.pattern.level=%5p [${spring.application.name:},%X{traceId:-},%X{spanId:-}]

或使用YAML格式:

yaml 复制代码
logging:
  pattern:
    level: "%5p [${spring.application.name:},%X{traceId:-},%X{spanId:-}]"

示例控制器代码

创建一个简单的控制器以验证Trace ID是否正常工作。

java 复制代码
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TraceController {
    private static final Logger logger = LoggerFactory.getLogger(TraceController.class);

    @GetMapping("/trace")
    public String trace() {
        logger.info("This is a log message with Trace ID");
        return "Trace ID is working!";
    }
}

启用Zipkin集成(可选)

如果需要将跟踪数据发送到Zipkin服务器,配置application.properties

properties 复制代码
spring.zipkin.base-url=http://localhost:9411
spring.sleuth.sampler.probability=1.0

或YAML格式:

yaml 复制代码
spring:
  zipkin:
    base-url: http://localhost:9411
  sleuth:
    sampler:
      probability: 1.0

日志输出验证

启动应用并访问/trace端点,检查日志输出。日志中应包含Trace ID和Span ID,格式如下:

csharp 复制代码
INFO [my-application,3c7a8b1e2f6d4a5b,9e1f0a3b5c7d8e2f] This is a log message with Trace ID

自定义日志字段

如果需要自定义日志字段,可以在日志配置中添加更多Sleuth提供的变量:

properties 复制代码
logging.pattern.level=%d{yyyy-MM-dd HH:mm:ss} [%X{traceId:-},%X{spanId:-},%X{parentId:-}] %-5level %logger{36} - %msg%n

跨服务追踪

确保所有微服务都添加了Spring Cloud Sleuth依赖。通过HTTP调用(如RestTemplate或Feign)时,Trace ID会自动传递。

java 复制代码
import org.springframework.web.client.RestTemplate;

public class SomeService {
    private final RestTemplate restTemplate;

    public SomeService(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }

    public String callAnotherService() {
        return restTemplate.getForObject("http://another-service/trace", String.class);
    }
}

异步任务支持

对于异步任务,使用@Async注解时,Trace ID会自动传递。确保启用异步支持:

java 复制代码
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

@Service
public class AsyncService {
    @Async
    public void asyncMethod() {
        // 异步方法中的日志会包含Trace ID
    }
}

手动创建Span

如果需要手动创建Span,可以使用Tracer接口:

java 复制代码
import org.springframework.cloud.sleuth.Tracer;
import org.springframework.stereotype.Service;

@Service
public class CustomTraceService {
    private final Tracer tracer;

    public CustomTraceService(Tracer tracer) {
        this.tracer = tracer;
    }

    public void customTrace() {
        var span = tracer.nextSpan().name("custom-span").start();
        try {
            // 业务逻辑
        } finally {
            span.end();
        }
    }
}

测试验证

编写测试用例验证Trace ID是否正常工作:

java 复制代码
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate;

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class TraceTest {
    @Autowired
    private TestRestTemplate restTemplate;

    @Test
    public void testTraceId() {
        String response = restTemplate.getForObject("/trace", String.class);
        // 验证日志输出中是否包含Trace ID
    }
}

注意事项

  • 确保所有服务使用相同的日志格式配置。
  • 在生产环境中,设置适当的采样率(如spring.sleuth.sampler.probability=0.1)。
  • 如果需要更复杂的追踪功能,考虑使用Zipkin或Jaeger等分布式追踪系统。
相关推荐
vx_bisheyuange2 小时前
基于SpringBoot的在线互动学习网站设计
java·spring boot·spring·毕业设计
roman_日积跬步-终至千里2 小时前
【源码分析】StarRocks TRUNCATE 语句执行流程:从 SQL 到数据清空的完整旅程
java·数据库·sql
雨中飘荡的记忆2 小时前
Spring状态机深度解析:从入门到生产实战
java·spring
Kings902 小时前
线程池导致的 shutdown失败的完整排查过程
java·spring boot
在坚持一下我可没意见2 小时前
Spring 后端安全双剑(下篇):JWT 无状态认证 + 密码加盐加密实战
java·开发语言·spring boot·后端·安全·spring
程序媛青青2 小时前
spring boot 和 spring cloud 的区别
spring boot·后端·spring cloud
我怎么想不到2 小时前
SpringBoot单体多模块项目环境搭建
后端
期待のcode2 小时前
MyBatis-Plus通用枚举
java·数据库·后端·mybatis·springboot