关于springboot引入traceid来保障可观测型

概述:

引入traceid是为了让每个用户请求进来,给每个线程分配一个标识,也就是traceid,然后回头,可以区分,哪个用户,在请求接口的,在接口的哪一步除了问题,当然,这里也要合适的使用日志。

我们这里就对这个使用traceid,以及遇到错误。这个全流程的知识点做一点总结。这样如果是涉及traceid的问题的时候可以得到解决。

1.如何引入traceid

哪个依赖里会携带traceid

2.traceid需要做配置吗,需要配置什么东西

3.在哪里可以看到traceid是否生效。

TraceId 全流程使用指南

一、如何引入TraceId

  1. 主要依赖
    Spring Cloud Sleuth(或新版整合的 Micrometer Tracing)是最常用的TraceId实现方案:

xml

xml 复制代码
<!-- Spring Boot 2.x + Spring Cloud 3.x -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>

<!-- Spring Boot 3.x + Spring Cloud 4.x -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-sleuth-o11y</artifactId>
</dependency>

<!-- 或者使用 Micrometer Tracing -->
<dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-tracing-bridge-brave</artifactId>
</dependency>
  1. 链路传递的核心组件
    Brave/Zipkin:分布式追踪库

MDC (Mapped Diagnostic Context):线程上下文存储TraceId

HTTP请求拦截器:自动在HTTP头传递TraceId

消息队列拦截器:如RabbitMQ/Kafka的TraceId传递

二、TraceId配置

  1. 基本配置
    yaml

application.yml

xml 复制代码
spring:
  sleuth:
    enabled: true
    # TraceId采样率,1.0表示100%采样
    probability: 1.0
复制代码
# 配置示例(不同版本可能不同)
trace:
  id-length: 32  # TraceId长度
  propagation:
    type: B3  # B3, W3C等传播格式
  1. 日志配置
    需要在日志模式中添加TraceId占位符:

xml

xml 复制代码
<!-- logback-spring.xml -->
<configuration>
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <!-- 关键:添加[traceId]字段 -->
            <pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] [%X{traceId:-}] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>
</configuration>
  1. 自定义配置
    java
java 复制代码
@Configuration
public class TraceConfig {
    
    @Bean
    public Sampler alwaysSampler() {
        return Sampler.ALWAYS_SAMPLE; // 始终采样
    }
    
    // 自定义TraceId生成规则
    @Bean
    public IdGenerator traceIdGenerator() {
        return new IdGenerator() {
            @Override
            public String generateTraceId() {
                // 自定义TraceId生成逻辑
                return "myapp-" + UUID.randomUUID().toString().replace("-", "");
            }
        };
    }
}

三、验证TraceId是否生效

  1. 查看日志输出
    启动应用后,调用任意接口,查看控制台日志:

text

java 复制代码
2024-01-15 10:30:25 [http-nio-8080-exec-1] [3f8a4b5c6d7e8f9a] INFO  c.example.controller.UserController - 用户查询开始
如果有[3f8a4b5c6d7e8f9a]这样的TraceId显示,说明生效。
  1. 通过API验证
    java
java 复制代码
@RestController
@RequestMapping("/debug")
public class DebugController {
    
    @GetMapping("/trace")
    public Map<String, String> getTraceInfo() {
        // 从MDC获取TraceId
        String traceId = org.slf4j.MDC.get("traceId");
        
        // 或者使用Tracer API
        String spanId = Tracing.currentTracer().currentSpan().context().spanIdString();
        
        return Map.of(
            "traceId", traceId,
            "spanId", spanId
        );
    }
}

访问 /debug/trace 查看返回的TraceId。

  1. 验证方法
    验证方式 操作步骤 预期结果
    查看应用日志 调用接口,观察日志格式 每条日志前都有TraceId
    HTTP头检查 查看请求/响应头的X-B3-TraceId 存在TraceId值
    链路调用验证 服务间调用,查看各服务日志 TraceId保持一致
    Zipkin界面 访问Zipkin UI (localhost:9411) 能看到完整的调用链路
  2. 快速验证脚本
    bash

调用接口并显示TraceId

curl -v http://localhost:8080/api/user/1 2>&1 | grep -i "trace|x-b3"

或者使用jq格式化输出

curl -s http://localhost:8080/api/user/1 | jq '.'

四、常见问题排查

  1. TraceId不显示
    原因1:日志pattern没有配置%X{traceId}

解决方案:检查logback配置

原因2:采样率设置为0

解决方案:设置spring.sleuth.sampler.probability=1.0

原因3:异步线程丢失TraceId

解决方案:

java

// 异步任务需要手动传递TraceId

java 复制代码
@Async
public CompletableFuture<String> asyncMethod() {
    // 从父线程获取TraceId
    String traceId = MDC.get("traceId");
    return CompletableFuture.supplyAsync(() -> {
        MDC.put("traceId", traceId); // 设置到子线程
        try {
            return doSomething();
        } finally {
            MDC.clear();
        }
    });
}
  1. 跨服务TraceId丢失
    检查点:

确认服务间使用相同的传播格式(B3/W3C)

确认HTTP客户端配置了Tracing拦截器

检查网关是否透传TraceId头

  1. 自定义组件集成
    java
java 复制代码
@Component
public class CustomComponent {
    // 手动获取当前TraceId
    public void logWithTrace() {
        Tracer tracer = Tracing.currentTracer();
        Span span = tracer.currentSpan();
        if (span != null) {
            String traceId = span.context().traceIdString();
            logger.info("[TraceId: {}] 自定义组件执行", traceId);
        }
    }
}

五、最佳实践建议

日志规范:在所有微服务中使用统一的日志格式

网关透传:确保API网关透传TraceId相关HTTP头

异步处理:对线程池和消息队列做好TraceId传递

监控告警:将TraceId集成到错误监控系统

开发调试:开发环境可设置100%采样率,生产环境适当调整

通过以上配置和验证方法,可以确保TraceId在整个分布式系统中正确传递和显示,便于问题排查和链路追踪。

相关推荐
晚霞的不甘7 分钟前
CANN 编译器深度解析:UB、L1 与 Global Memory 的协同调度机制
java·后端·spring·架构·音视频
SunnyDays10119 分钟前
使用 Java 冻结 Excel 行和列:完整指南
java·冻结excel行和列
喵叔哟18 分钟前
06-ASPNETCore-WebAPI开发
服务器·后端·c#
摇滚侠20 分钟前
在 SpringBoot 项目中,开发工具使用 IDEA,.idea 目录下的文件需要提交吗
java·spring boot·intellij-idea
云姜.25 分钟前
java多态
java·开发语言·c++
李堇28 分钟前
android滚动列表VerticalRollingTextView
android·java
泉-java1 小时前
第56条:为所有导出的API元素编写文档注释 《Effective Java》
java·开发语言
Charlie_lll1 小时前
力扣解题-移动零
后端·算法·leetcode
zfoo-framework1 小时前
帧同步和状态同步
java
charlotte102410241 小时前
高并发:关于在等待学校教务系统选课时的碎碎念
java·运维·网络