当前位置: 首页 > article >正文

调用链追踪(Trace ID)

前言:

在 Java 中实现 调用链追踪(Trace ID) 通常用于分布式系统中跟踪请求的完整链路,常见的实现方式包括手动编码或使用开源框架(如 SkyWalkingZipkinSpring Cloud Sleuth 等)。以下是具体实现方法及示例:

1. 手动实现 Trace ID

通过 ThreadLocal 或 MDC(Mapped Diagnostic Context)存储 Trace ID,并在请求链路中传递。

步骤 1:定义 Trace ID 工具类
import org.slf4j.MDC;
import java.util.UUID;

public class TraceIdUtil {

    private static final String TRACE_ID_KEY = "traceId";
    private static final ThreadLocal<String> traceIdHolder = new ThreadLocal<>();

    // 生成或获取当前 Trace ID
    public static String getOrGenerateTraceId() {
        String traceId = MDC.get(TRACE_ID_KEY);
        if (traceId == null) {
            traceId = UUID.randomUUID().toString().replace("-", "");
            MDC.put(TRACE_ID_KEY, traceId);
            traceIdHolder.set(traceId);
        }
        return traceId;
    }

    // 清除 Trace ID(防止内存泄漏)
    public static void clear() {
        MDC.remove(TRACE_ID_KEY);
        traceIdHolder.remove();
    }
}

步骤 2:在 HTTP 请求中传递 Trace ID

通过拦截器在请求头中添加 Trace ID:

import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;
import java.io.IOException;

public class TraceIdInterceptor implements ClientHttpRequestInterceptor {
    @Override
    public ClientHttpResponse intercept(
        HttpRequest request, byte[] body, ClientHttpRequestExecution execution
    ) throws IOException {
        String traceId = TraceIdUtil.getOrGenerateTraceId();
        request.getHeaders().add("X-Trace-Id", traceId);
        return execution.execute(request, body);
    }
}

步骤 3:在日志中输出 Trace ID

配置 logback.xml,在日志模板中添加 %X{traceId}

<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] [%X{traceId}] %-5level %logger{36} - %msg%n</pattern>

2. 使用 Spring Cloud Sleuth + Zipkin(推荐)

Spring Cloud Sleuth 自动集成 Trace ID,Zipkin 提供可视化追踪。

步骤 1:添加依赖
<!-- Spring Cloud Sleuth -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>

<!-- Zipkin 上报 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-sleuth-zipkin</artifactId>
</dependency>
步骤 2:配置 application.yml

spring:
  sleuth:
    sampler:
      probability: 1.0  # 采样率(1.0=100%上报)
  zipkin:
    base-url: http://localhost:9411  # Zipkin 服务地址
 
步骤 3:查看调用链

启动 Zipkin 服务后,访问 http://localhost:9411 查看完整的调用链路。


3. 使用 SkyWalking

SkyWalking 是一款开源的 APM 系统,支持自动链路追踪。

步骤 1:下载并启动 SkyWalking

# 下载 SkyWalking
wget https://archive.apache.org/dist/skywalking/9.6.0/apache-skywalking-apm-9.6.0.tar.gz
tar -zxvf apache-skywalking-apm-9.6.0.tar.gz
cd apache-skywalking-apm-bin

# 启动 SkyWalking
bin/startup.sh
 
步骤 2:Java 应用接入 Agent

在 JVM 启动参数中添加 Agent:

-javaagent:/path/to/skywalking-agent/skywalking-agent.jar
-Dskywalking.agent.service_name=your-service-name
-Dskywalking.collector.backend_service=localhost:11800
 

4. 异步线程传递 Trace ID

使用 TransmittableThreadLocal 解决线程池中 Trace ID 丢失问题:

import com.alibaba.ttl.TransmittableThreadLocal;

public class TraceContext {
    private static final TransmittableThreadLocal<String> traceIdHolder = 
        new TransmittableThreadLocal<>();

    public static void setTraceId(String traceId) {
        traceIdHolder.set(traceId);
    }

    public static String getTraceId() {
        return traceIdHolder.get();
    }

    public static void clear() {
        traceIdHolder.remove();
    }
}

// 在线程池任务中调用
ExecutorService executor = TtlExecutors.getTtlExecutorService(Executors.newFixedThreadPool(10));
executor.submit(() -> {
    System.out.println("Trace ID: " + TraceContext.getTraceId());
});
 

关键点总结

方案适用场景优点缺点
手动实现 Trace ID简单项目或框架不支持链路追踪时轻量级,无依赖需自行处理传递逻辑
Spring Cloud SleuthSpring Cloud 微服务项目自动化集成,支持 Zipkin 可视化依赖 Spring 生态
SkyWalking企业级监控,多语言支持功能强大,支持全链路追踪需部署额外服务

根据项目需求选择合适方案!


http://www.kler.cn/a/572729.html

相关文章:

  • 关于tresos Studio(EB)的MCAL配置之GPT
  • 计算机毕设-基于springboot的网上商城系统的设计与实现(附源码+lw+ppt+开题报告)
  • VSTO(C#)Excel开发起步
  • unittest框架 核心知识的系统复习及与pytest的对比
  • 厦门大学:《DeepSeek大模型赋能高校教学和科研报告》(120页PPT,建议收藏)
  • Milvus 数据批量导出实战:Python 代码解析
  • 【深度剖析】古德-图灵估计:从密码破译到NLP的统计革命
  • react精简面试题
  • 金融术语:Loan origination理解
  • RockyLinux9.5 虚拟机安装、配置及XShell连接
  • GaussianCity:实时生成城市级数字孪生基底的技术突破
  • 报错Non-terminating decimal expansion; no exact representable decimal result
  • 【YOLO V5】目标检测 WSL2 AutoDL VScode SSH
  • MySQL环境搭建
  • 充分必要条件
  • Spring Boot 3 整合 MinIO 实现分布式文件存储
  • 大模型基石——Transformer介绍
  • 蓝桥杯4T平台(频率测量显示)
  • FPGA有关HDMI的一些知识,程序源自bilibi正点原子
  • Ubuntu20.04双系统安装及软件安装(一):系统安装