Skip to content

链路追踪 Sleuth + Zipkin

TIP

在微服务架构中,一个请求会经过多个服务。链路追踪可以帮助理解请求的完整调用链,快速定位性能瓶颈和故障点。

核心概念

概念说明
TraceId一次请求的全局唯一 ID
SpanId每个服务调用的唯一 ID
ParentId父 Span 的 ID,形成调用树

Sleuth 集成

引入依赖

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

效果

添加 Sleuth 后,日志会自动包含 TraceId 和 SpanId:

2024-01-01 10:00:00.123 [user-service, trace-id, span-id] INFO  UserController
2024-01-01 10:00:00.456 [order-service, trace-id, span-id] INFO  OrderController

可以看到两个日志的 TraceId 相同,表示它们是同一次请求的调用链。

Zipkin 集成

Zipkin 用于收集和展示链路数据。

部署 Zipkin

bash
docker run -d -p 9411:9411 openzipkin/zipkin

配置数据上报

yaml
spring:
  sleuth:
    sampler:
      probability: 1.0       # 采样率 100%(生产环境建议降低)
  zipkin:
    base-url: http://localhost:9411
    sender:
      type: web               # 通过 HTTP 上报

自定义 Span

java
@Service
public class OrderService {

    @Autowired
    private Tracer tracer;

    public Order createOrder(Order order) {
        // 创建自定义 Span
        Span span = tracer.nextSpan().name("validate-order").start();
        try (Tracer.SpanInScope ws = tracer.withSpanInScope(span)) {
            // 执行业务逻辑
            validateOrder(order);
        } finally {
            span.finish();
        }
        return orderDao.save(order);
    }
}

Zipkin 控制台

Zipkin UI 提供:

  • 查找:按 TraceId 或条件搜索链路
  • 依赖图:服务间调用关系
  • 时间线:各 Span 的耗时分布

Brave(Sleuth 底层)

Sleuth 底层基于 Brave 实现,也可直接使用 Brave API:

java
@Autowired
private Tracer tracer;

public void businessMethod() {
    Span span = tracer.nextSpan()
        .name("business-method")
        .tag("key", "value")
        .start();

    try {
        // 业务代码
    } finally {
        span.finish();
    }
}

TIP

  • 生产环境中采样率建议设为 0.1~0.01(10%~1%),避免过多数据
  • Zipkin 数据可以持久化到 Elasticsearch 实现长时间存储