链路追踪实现完全指南
前言
链路追踪是微服务架构中实现可观测性的关键组件,用于追踪一个请求在分布式系统中的完整调用路径。本文将详细介绍链路追踪的实现机制、工具选择和最佳实践。
一、链路追踪概述
1.1 分布式追踪原理
┌─────────────────────────────────────────────────────┐ │ Distributed Tracing Flow │ │ │ │ Client │ │ │ │ │ │ Trace: abc123 │ │ │ Span: 1 │ │ ▼ │ │ Service A ────────────────────────────────────── │ │ │ │ Trace: abc123 │ │ │ │ Span: 2 │ │ ▼ ▼ │ │ Service B Service C │ │ │ │ Trace: abc123 │ │ │ │ Span: 3 (Child of 2) │ │ │ ▼ │ │ │ Database │ │ │ │ └─────────────────────────────────────────────────────┘1.2 核心概念
- Trace:完整的请求链路
- Span:链路中的一个操作单元
- Annotation:附带的时间戳事件
二、Sleuth集成
2.1 依赖配置
<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>2.2 Sleuth配置
spring: application: name: order-service zipkin: base-url: http://zipkin-server:9411 sender: type: web sampler: probability: 1.0 sleuth: sampler: probability: 1.0 rate: 1000 instrumentation: web: enabled: true jdbc: enabled: true spans: maximumSpans: 1000 keepSpansWithLocalComponents: true三、OpenTelemetry集成
3.1 OpenTelemetry配置
spring: application: name: order-service otlp: tracing: endpoint: http://otel-collector:4318/v1/traces@Configuration public class OpenTelemetryConfig { @Bean public OpenTelemetry openTelemetry() { return OpenTelemetry.builder() .setTracerProvider(tracerProvider()) .build(); } @Bean public Tracer tracer(OpenTelemetry openTelemetry) { return openTelemetry.getTracer("order-service", "1.0.0"); } }3.2 自定义Span
@Service @RequiredArgsConstructor public class OrderService { private final Tracer tracer; public Order createOrder(OrderCreateRequest request) { Span span = tracer.spanBuilder("createOrder") .setAttribute("order.customerId", request.getCustomerId()) .setAttribute("order.amount", request.getAmount().doubleValue()) .setSpanKind(SpanKind.INTERNAL) .startSpan(); try (Scope scope = span.makeCurrent()) { Order order = orderRepository.save(request.toOrder()); span.setAttribute("order.id", order.getId()); span.setAttribute("order.status", order.getStatus().name()); return order; } catch (Exception e) { span.recordException(e); span.setStatus(StatusCode.ERROR, e.getMessage()); throw e; } finally { span.end(); } } }四、总结
链路追踪是微服务可观测性的核心组件。通过Sleuth或OpenTelemetry实现链路追踪,可以清晰地看到请求在各个服务间的调用关系,便于性能分析和问题定位。