知识模块
☕ Java 知识模块
九、分布式系统
分布式链路追踪

分布式链路追踪

什么是链路追踪?

在微服务架构中,一个请求可能经过多个服务,链路追踪用于追踪请求的完整调用链路。

请求 → 网关 → 订单服务 → 库存服务 → 数据库

              支付服务

              通知服务

链路追踪记录:
- 每个服务的处理时间
- 调用关系
- 错误信息

核心概念

概念说明
Trace完整调用链,一个 Trace 包含多个 Span
Span单个服务的调用,包含开始时间、结束时间、操作名
TraceId全局唯一 ID,标识整个调用链
SpanId标识单个 Span
ParentSpanId父 Span 的 ID

调用链结构

TraceId: abc123

Span A (SpanId: 1, Parent: null)

    ├── Span B (SpanId: 2, Parent: 1)
    │       │
    │       └── Span D (SpanId: 4, Parent: 2)

    └── Span C (SpanId: 3, Parent: 1)

主流方案

方案说明特点
SkyWalking国产开源无侵入、功能全
ZipkinTwitter 开源轻量级
JaegerUber 开源云原生
Pinpoint韩国开源UI 美观

SkyWalking

架构

┌─────────────────────────────────────────────────────────────┐
│                       SkyWalking OAP                        │
│                    (分析、聚合、存储)                       │
└─────────────────────────────────────────────────────────────┘
         ↑                                        ↑
         │ gRPC                                   │ 查询
         │                                        │
┌────────┴────────┐                    ┌─────────┴─────────┐
│   SkyWalking    │                    │   SkyWalking UI   │
│   Java Agent    │                    │                   │
│  (无侵入探针)  │                    │   (可视化界面)   │
└────────┬────────┘                    └───────────────────┘

         │ 监控

┌─────────────────────────────────────────────────────────────┐
│                      应用服务                                │
│   OrderService → StockService → PaymentService             │
└─────────────────────────────────────────────────────────────┘

使用方式

1. 下载 Agent

wget https://archive.apache.org/dist/skywalking/java-agent/8.16.0/apache-skywalking-java-agent-8.16.0.tgz
tar -xzf apache-skywalking-java-agent-8.16.0.tgz

2. 启动应用(附加 Agent)

java -javaagent:/path/to/skywalking-agent.jar \
     -Dskywalking.agent.service_name=order-service \
     -Dskywalking.collector.backend_service=localhost:11800 \
     -jar order-service.jar

3. 访问 UI

http://localhost:8080

功能

功能说明
拓扑图服务调用关系可视化
链路追踪查看单个请求的完整链路
性能指标响应时间、吞吐量、错误率
告警性能异常自动告警

Spring Cloud Sleuth + Zipkin

依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-sleuth-zipkin</artifactId>
</dependency>

配置

spring:
  sleuth:
    sampler:
      probability: 1.0  # 采样率 100%
  zipkin:
    base-url: http://localhost:9411

自定义 Span

@Service
public class OrderService {
    
    @Autowired
    private Tracer tracer;
    
    public Order createOrder(OrderDTO dto) {
        // 创建自定义 Span
        Span span = tracer.nextSpan().name("create-order");
        try (Tracer.SpanInScope ws = tracer.withSpan(span.start())) {
            // 业务逻辑
            return doCreateOrder(dto);
        } finally {
            span.end();
        }
    }
}

日志集成

<!-- logback-spring.xml -->
<configuration>
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss} [%X{traceId},%X{spanId}] [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>
</configuration>

TraceId 传递

HTTP 传递

请求头:
X-Trace-Id: abc123
X-Span-Id: 1
X-Parent-Span-Id: null

MQ 传递

// 生产者
rabbitTemplate.convertAndSend(queue, message, msg -> {
    msg.getMessageProperties().setHeader("X-Trace-Id", traceId);
    return msg;
});
 
// 消费者
@RabbitListener(queues = "order.queue")
public void handle(Message message, @Header("X-Trace-Id") String traceId) {
    MDC.put("traceId", traceId);
    // 处理业务
    MDC.remove("traceId");
}

面试高频问题

Q1: 链路追踪的实现原理?

  1. 在请求入口生成 TraceId
  2. 通过 HTTP Header / MQ Header 传递 TraceId
  3. 每个服务创建 Span,记录处理时间
  4. 异步上报到链路追踪系统

Q2: SkyWalking 和 Zipkin 的区别?

对比SkyWalkingZipkin
侵入性无(Agent)低(依赖)
功能更全面基础
性能影响
存储ES/MySQL 等内存/ES/MySQL

Q3: 采样率如何设置?

  • 开发环境:100%
  • 生产环境:10%-50%(根据流量调整)
  • 异常请求:100%

Q4: TraceId 如何保证全局唯一?

UUID 或 Snowflake 算法生成。

总结

分布式链路追踪核心要点:
1. 核心概念:Trace、Span、TraceId、SpanId
2. 主流方案:SkyWalking(无侵入)、Zipkin(轻量)
3. 传递方式:HTTP Header、MQ Header
4. 功能:拓扑图、链路追踪、性能指标、告警