06-分布式追踪详解
Spring Cloud 分布式追踪详解一、知识概述分布式追踪是微服务架构中诊断和监控系统的重要技术,它能够追踪请求在多个服务之间的调用链路,帮助开发者快速定位性能瓶颈和故障原因。Spring Cloud 提供了 Spring Cloud Sleuth 和 Micrometer Tracing 作为分布式追踪解决方案。分布式追踪的核心概念:Trace:一次完整请求的追踪标识Span:单个服务的处理过程Annotation:事件记录点采样率:控制追踪数据的采集比例理解分布式追踪的原理,是构建可观测微服务系统的重要技能。二、知识点详细讲解2.1 分布式追踪模型客户端请求 │ ▼ 服务 A ───────────────────────────────────── │ Span (spanId=1, traceId=abc) │ │ cs: Client Send │ │ sr: Server Receive │ │ │ │ ──── 调用服务 B ──── │ │ │ │ │ ▼ │ │ 服务 B ───────────────── │ │ Span (spanId=2) │ │ │ parentSpanId=1 │ │ │ │ │ │ ──── 调用服务 C ─── │ │ │ │ │ │ ▼ │ │ │ 服务 C ───── │ │ │ Span (spanId=3) │ │ │ parentSpanId=2 │ │ │ │ │ │ ─── 返回 ──│ │ │ │ │ ───── 返回 ─────────│ │ │ │ ss: Server Send │ │ cr: Client Receive │ └──────────────────────────────────────┘2.2 核心概念Trace ID标识一次完整的请求链路在整个调用链中保持不变通常使用 64 位或 128 位 IDSpan ID标识一个服务处理单元每个服务调用生成新的 Span包含父 Span ID(parentSpanId)注解(Annotation)cs (Client Send):客户端发起请求sr (Server Receive):服务端接收请求ss (Server Send):服务端发送响应cr (Client Receive):客户端接收响应2.3 追踪系统对比系统特点适用场景Zipkin简单易用中小规模Jaeger高性能大规模SkyWalking功能全面企业级Grafana Tempo成本低云原生2.4 采样策略全量采样:采集所有请求(不推荐)比例采样:按比例采集(如 10%)限流采样:限制每秒采样数三、代码示例3.1 Spring Cloud Sleuth 基础配置!-- pom.xml --dependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-starter-sleuth/artifactId/dependency# application.ymlspring:application:name:user-servicesleuth:sampler:probability:1.0# 采样率 100%(生产环境建议降低)web:skip-pattern:/actuator.*,/health,/infopropagation:type:B3# 传播类型3.2 集成 ZipkindependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-sleuth-zipkin/artifactId/dependencyspring:zipkin:base-url:http://localhost:9411sender:type:websleuth:sampler:probability:0.1# 10% 采样率3.3 自定义 Spanimportorg.springframework.cloud.sleuth.Span;importorg.springframework.cloud.sleuth.Tracer;importorg.springframework.stereotype.Service;@ServicepublicclassUserService{@AutowiredprivateTracertracer;publicUserDTOgetUserById(Longid){// 创建自定义 SpanSpanspan=tracer.nextSpan().name("getUserById");try(Tracer.SpanInScopews=tracer.withSpan(span.start())){// 添加标签span.tag("userId",String.valueOf(id));span.event("start-query");// 执行业务逻辑UserDTOuser=queryUserFromDb(id);span.event("end-query");returnuser;}catch(Exceptione){span.error(e);throwe;}finally{span.end();}}privateUserDTOqueryUserFromDb(Longid){// 数据库查询returnnewUserDTO();}}3.4 使用注解追踪importorg.springframework.cloud.sleuth.annotation.NewSpan;importorg.springframework.cloud.sleuth.annotation.SpanTag;importorg.springframework.stereotype.Service;@ServicepublicclassOrderService{// 自动创建 Span@NewSpan("createOrder")public