乐途乐途
主页
  • 计算机基础

    • TCP/IP
    • Linux
    • HTTP
  • 数据库

    • SQL
    • MySQL 5.7
  • 编程语言

    • C
    • C++
    • Java SE
    • Python2
    • Python3
  • 数据格式

    • JSON
    • XML
  • 认证与安全

    • JWT
  • 工具

    • Markdown
  • Git

    • GitFlow
  • Quartz

    • Quartz
  • Java

    • Maven 入门
    • Maven 进阶
    • MyBatis
    • Spring
    • Spring MVC
  • Java

    • Spring Boot
    • Spring Cloud
    • Spring Cloud Alibaba
    • Spring Security
    • Spring AI
    • Spring Batch
    • Kafka
    • Java 设计模式
  • 缓存

    • Redis
  • 搜索引擎

    • Elasticsearch
  • 分布式协调

    • ZooKeeper
联系
阿里云
主页
  • 计算机基础

    • TCP/IP
    • Linux
    • HTTP
  • 数据库

    • SQL
    • MySQL 5.7
  • 编程语言

    • C
    • C++
    • Java SE
    • Python2
    • Python3
  • 数据格式

    • JSON
    • XML
  • 认证与安全

    • JWT
  • 工具

    • Markdown
  • Git

    • GitFlow
  • Quartz

    • Quartz
  • Java

    • Maven 入门
    • Maven 进阶
    • MyBatis
    • Spring
    • Spring MVC
  • Java

    • Spring Boot
    • Spring Cloud
    • Spring Cloud Alibaba
    • Spring Security
    • Spring AI
    • Spring Batch
    • Kafka
    • Java 设计模式
  • 缓存

    • Redis
  • 搜索引擎

    • Elasticsearch
  • 分布式协调

    • ZooKeeper
联系
阿里云
  • 学习路径
  • 第1章 微服务与 Spring Cloud 概述

    • 微服务与 Spring Cloud 概述
  • 第2章 服务注册与发现

    • Eureka 服务注册与发现
    • Consul 服务注册与发现
  • 第3章 客户端负载均衡

    • Ribbon 客户端负载均衡
    • Spring Cloud LoadBalancer
  • 第4章 声明式服务调用

    • Feign 声明式 HTTP 客户端
    • OpenFeign 高级特性与 Spring Cloud 集成
  • 第5章 服务容错与熔断

    • Resilience4j 服务容错与熔断
    • Sentinel 流量控制与熔断降级
  • 第6章 配置中心

    • Spring Cloud Config 配置中心
  • 第7章 API 网关

    • Spring Cloud Gateway 现代化 API 网关
    • Zuul 网关(已进入维护模式)
  • 第8章 消息驱动的微服务

    • Spring Cloud Stream 消息驱动的微服务
  • 第9章 分布式追踪与监控

    • Sleuth + Zipkin 分布式链路追踪
  • 第10章 最佳实践与面试考点

    • Spring Cloud 最佳实践与面试考点

Sleuth + Zipkin 分布式链路追踪

导学

双十一结束后,大翔在复盘会上问了一个问题:"27 号凌晨 1 点,用户小王的订单支付超时了。问题是出在订单服务本身、支付服务响应慢、还是网络抖动?谁能告诉我这笔订单到底经过了哪些服务,各自耗时多少?"

所有人沉默了。小崔翻了半天日志:"订单服务的日志在文件 A,支付服务的在文件 B,库存的又在另一个文件夹...而且要按 Trace ID 手动关联。"

白歌说:"这就是分布式追踪要解决的问题。Spring Cloud 提供了 Micrometer Tracing + Zipkin 方案。"


定位与问题场景

微服务架构中排查问题的三大痛点:


核心原理

Trace 和 Span

  • Trace(追踪):一次完整的请求链路,由唯一的 Trace ID 标识
  • Span(跨度):链路中的一个基本工作单元,记录操作名称、开始/结束时间、标签和事件
  • 上下文传播:Trace ID 和 Span ID 通过 HTTP Header(traceparent)在服务间传递

Sleuth 演进(Spring Boot 3.x 重要变更)

关键变更:Spring Cloud Sleuth 已进入维护模式。Spring Boot 3.x + Spring Cloud 2022.0.x 起,使用 Micrometer Tracing 作为统一的可观测性门面。

版本追踪方案依赖
Spring Boot 2.xSpring Cloud Sleuthspring-cloud-starter-sleuth
Spring Boot 3.xMicrometer Tracingmicrometer-tracing-bridge-brave + zipkin-reporter-brave

完整示例:飞翔科技全链路追踪

场景描述

订单服务 → 库存服务 → 支付服务的调用链路,使用 Micrometer Tracing + Zipkin 实现全链路追踪和可视化。

操作前后对比:

维度引入 Tracing 前引入 Tracing 后
跨服务日志关联手动通过时间戳猜测Trace ID 自动串联所有服务日志
调用链拓扑凭记忆画架构图Zipkin UI 自动生成拓扑图
耗时瓶颈各服务日志分开看Span 树直观展示每个环节耗时

步骤一:依赖引入

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-tracing-bridge-brave</artifactId>
</dependency>
<dependency>
    <groupId>io.zipkin.reporter2</groupId>
    <artifactId>zipkin-reporter-brave</artifactId>
</dependency>

步骤二:配置

spring:
  application:
    name: feixiang-order-service

management:
  tracing:
    sampling:
      probability: 1.0    # 100% 采样(开发环境;生产环境建议 0.1)
  zipkin:
    tracing:
      endpoint: http://localhost:9411/api/v2/spans

步骤三:业务代码(无需额外注解)

@RestController
@Slf4j
public class OrderController {
    @Autowired
    private RestTemplate restTemplate;

    @GetMapping("/order/{orderId}")
    public Order getOrder(@PathVariable String orderId) {
        // Trace ID 自动注入 MDC,日志自动携带
        log.info("查询订单:orderId={}", orderId);

        // 调用库存服务(Trace 自动传播)
        StockDTO stock = restTemplate.getForObject(
            "http://FEIXIANG-INVENTORY-SERVICE/inventory/" + orderId,
            StockDTO.class
        );

        // 调用支付服务(Trace 自动传播)
        PaymentDTO payment = restTemplate.getForObject(
            "http://FEIXIANG-PAYMENT-SERVICE/payment/" + orderId,
            PaymentDTO.class
        );

        return Order.builder()
                .orderId(orderId)
                .stock(stock)
                .payment(payment)
                .build();
    }
}

步骤四:自定义 Span

@RestController
public class OrderController {
    @Autowired
    private ObservationRegistry observationRegistry;

    @GetMapping("/order/create")
    public Order createOrder(@RequestBody OrderRequest request) {
        // 创建自定义 Span 记录业务操作
        return Observation.createNotStarted("order.create-business-logic", observationRegistry)
                .lowCardinalityKeyValue("order.type", request.getType())
                .observe(() -> {
                    // 业务逻辑
                    Order order = orderService.create(request);
                    log.info("订单创建成功:orderId={}", order.getId());
                    return order;
                });
    }
}

步骤五:启动 Zipkin Server

docker run -d --name zipkin \
  -p 9411:9411 \
  openzipkin/zipkin:3

访问 http://localhost:9411,输入 Trace ID 即可查看完整的调用链拓扑图和耗时分布。

步骤六:Logback 配置 Trace ID

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

日志输出示例(三个服务的日志中 Trace ID 一致):

# 订单服务
14:32:01.123 [http-nio-8080] INFO  [abc123] [span-1] OrderController - 查询订单:orderId=1001

# 库存服务
14:32:01.245 [http-nio-8081] INFO  [abc123] [span-2] InventoryController - 扣减库存

# 支付服务
14:32:01.567 [http-nio-8082] INFO  [abc123] [span-3] PaymentController - 发起支付

监控体系扩展

Prometheus + Grafana

management:
  endpoints:
    web:
      exposure:
        include: health,info,prometheus
  metrics:
    tags:
      application: ${spring.application.name}
# prometheus.yml
scrape_configs:
  - job_name: 'spring-boot-services'
    metrics_path: '/actuator/prometheus'
    static_configs:
      - targets: ['localhost:8080', 'localhost:8081', 'localhost:8082']

易错场景

1. Spring Boot 3.x 引入 spring-cloud-starter-sleuth 导致启动失败

Spring Boot 3.x 中 Sleuth 已被 Micrometer Tracing 替代。如果引入 spring-cloud-starter-sleuth,会产生冲突。

2. MDC 中的 Trace ID 键名变化

版本Trace ID MDC 键名
SleuthtraceId
Micrometer Tracing (Brave)traceId
Micrometer Tracing (OTel)trace_id

确保 logback 配置的 %X{...} 键名与使用的 Tracing Bridge 一致。

3. 异步线程 Trace ID 丢失

// ❌ 错误:异步线程中 Trace ID 丢失
@Async
public void sendNotification(String orderId) {
    log.info("发送通知");  // MDC 中没有 Trace ID
}

// ✅ 正确:使用 Context Propagation
@Async
public void sendNotification(String orderId) {
    try (var scope = observationRegistry.getCurrentObservation().openScope()) {
        log.info("发送通知");  // MDC 中有 Trace ID
    }
}

4. 生产环境 100% 采样导致性能下降

# ❌ 生产环境
management.tracing.sampling.probability: 1.0

# ✅ 生产环境:10% 采样
management.tracing.sampling.probability: 0.1

面试考点

Trace 和 Span 的区别?

Trace 是一次完整请求链路的全局标识(Trace ID),由一系列 Span 组成。Span 是链路中单个操作单元,记录操作名称、父子关系、开始/结束时间戳、标签和事件。一个 Trace 是一棵树,根 Span 是最初的请求入口,子 Span 是下游调用,所有 Span 共享同一个 Trace ID。

Sleuth 为什么被 Micrometer Tracing 取代?

Micrometer 是 Spring 生态的统一可观测性门面(Metrics + Tracing),Sleuth 是 Spring Cloud 的独立追踪方案。Micrometer Tracing 将追踪融入 Micrometer 体系,与 Micrometer Metrics 共享 Observation API,实现 Metrics + Traces 的统一。同时支持 Brave 和 OpenTelemetry 两种实现,给用户更多选择。

Zipkin、Jaeger、SkyWalking 的对比?

工具定位特点
Zipkin轻量追踪部署简单,资源占用小,仅追踪
Jaeger分布式追踪CNCF 项目,云原生,Uber 开源
SkyWalkingAPM 全栈追踪+指标+日志+拓扑+告警,探针无侵入

中小系统或仅需追踪 → Zipkin;全面可观测+国内生态 → SkyWalking;云原生/K8s → Jaeger。


小结

分布式追踪让微服务的"黑盒"调用变得透明。通过 Trace ID 串联分散的日志,通过 Zipkin 可视化调用链拓扑,排查问题时不再是盲人摸象。Micrometer Tracing 作为 Sleuth 的继任者,将追踪融入了 Spring 生态的一体化可观测体系。至此,Spring Cloud 的核心组件全部讲解完毕,最后一章我们进行最佳实践总结和面试考点梳理。