实现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等分布式追踪系统。
相关推荐
BlockChain88815 小时前
SpringBoot实战一:10分钟搭建企业级用户管理系统(20000字完整项目)
java·spring boot·后端
消失的旧时光-194315 小时前
第六课 · 6.1 从 JDBC 到 MyBatis:SQL 工程化是如何发生的?
java·sql·mybatis
拽着尾巴的鱼儿15 小时前
Springboot 缓存@Cacheable 使用
spring boot·后端·缓存
Jaxson Lin15 小时前
Java编程进阶:线程基础与实现方式全解析
java·开发语言
夜喵YM15 小时前
基于 Spire.XLS.Free for Java 实现无水印 Excel 转 PDF
java·pdf·excel
茶本无香15 小时前
设计模式之五—门面模式:简化复杂系统的统一接口
java·设计模式
bugcome_com15 小时前
脑力的“报废”是静悄悄的
后端·程序人生
她说可以呀15 小时前
网络基础初识
java·网络·java-ee
爱吃肉的鹏15 小时前
使用Flask在本地调用树莓派摄像头
人工智能·后端·python·flask·树莓派
没有bug.的程序员15 小时前
Java锁优化:从synchronized到CAS的演进与实战选择
java·开发语言·多线程·并发·cas·synchronized·