SpringCloud 核心组件解析:服务链路追踪
2026/6/13 15:53:57 网站建设 项目流程

SpringCloud 核心组件解析:服务链路追踪

技术栈:Spring Boot 3.2.0 + Spring Cloud 2023.0.0 +Micrometer Tracing+ Zipkin
已不维护:Spring Cloud Sleuth → 替代用 Micrometer Tracing


5.1 是什么 — 链路追踪的核心概念

5.1.1 生活化类比:快递追踪

你在淘宝买了 3 件商品,想知道它们到哪了:

快递单号 SF1234567890(Trace ID) ├── [扫描点 A] 北京分拣中心 12:00 → 12:05 (Span 1) │ └── [扫描点 B] 北京→上海 运输 12:05 → 18:00 (Span 2) │ └── [扫描点 C] 上海配送站 → 签收 18:30 (Span 3)
  • Trace ID = 快递单号:贯穿整个流程的唯一标识
  • Span = 扫描记录:每个环节的处理记录(时间、地点、操作)
  • Parent Span → Child Span:表达了调用层级关系

5.1.2 技术定义

在微服务中,一个用户请求可能经过 N 个服务。链路追踪就是给每个请求分配一个全局唯一 ID,记录它经过的每个服务及耗时。

用户 → Order Service (Span A, parent=null) │ HTTP 调用 ├→ Payment Service (Span B, parent=Span A) │ │ Feign 调用 │ └→ Account Service (Span C, parent=Span B) │ └→ Inventory Service (Span D, parent=Span A) Trace ID: 5f7a3b2c... 贯穿整棵树 Span ID: A/B/C/D... 每个节点一个 ID

5.2 为什么 — 没有链路追踪的痛点

5.2.1 场景

线上用户反馈"下单等了 10 秒才成功",已知调用链:Nginx → Gateway → Order → Payment → Account。

❓ 到底哪个环节慢了? ❓ 是数据库慢还是网络慢? ❓ 10s 里各环节分别占多少? ❓ 有没有哪个服务报错了?

没有链路追踪,排查方式 = 挨个服务查日志 + 靠时间戳对着拼。20 个服务时这是灾难。

5.2.2 Sleuth 的贡献与谢幕

Spring Cloud Sleuth 早期做了两件最重要的事:

  1. 自动生成 TraceId/SpanId并注入到日志 MDC
  2. 通过 HTTP Header 跨服务传播X-B3-TraceIdX-B3-SpanId

经典日志格式:

2024-10-20 10:00:01.123 INFO [order-service, abc123, def456, true] 创建订单成功 └─服务名 └─TraceId └─SpanId └─是否上报

⚠️ Spring Boot 3.x 中 Sleuth 被Micrometer Tracing取代,API 发生重大变化。


5.3 怎么做 — Micrometer Tracing + Zipkin 完整集成

5.3.1 小 Demo:先暴露痛点

在 Provider 中故意加延时模拟慢查询:

@GetMapping(value="/pay/get/{id}")publicResultData<Pay>getById(@PathVariable("id")Integerid){// 模拟慢查询:故意 sleep 62 秒try{TimeUnit.SECONDS.sleep(62);}catch(Exceptione){e.printStackTrace();}returnResultData.success(payService.getById(id));}

Consumer 调用后:不知道 Provider 内部耗时多少,日志里只有一个总耗时

5.3.2 6 个核心依赖详解

序号依赖GAV作用
1micrometer-tracing-bomio.micrometerBOM 版本管理,统一版本
2micrometer-tracingio.micrometer核心 API,创建 Trace/Span
3micrometer-tracing-bridge-braveio.micrometer将 Micrometer API 桥接到 Brave(Zipkin 的 Java 实现)
4micrometer-observationio.micrometerObservation API,统一 metrics/tracing/logging
5feign-micrometerio.github.openfeign让 Feign 客户端自动生成 Span
6zipkin-reporter-braveio.zipkin.reporter2将 Span 数据异步发送到 Zipkin Server
<!-- 父 POM 中统一管理版本 --><dependencyManagement><dependencies><dependency><groupId>io.micrometer</groupId><artifactId>micrometer-tracing-bom</artifactId><version>1.2.0</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement>

5.3.3 Provider 端配置

# 注意:Spring Boot 3.x 中配置前缀改变了!management:zipkin:tracing:endpoint:http://localhost:9411/api/v2/spans# Zipkin Server 地址tracing:sampling:probability:1.0# 采样率:开发=1.0(全部),生产=0.1(10%)

5.3.4 Consumer 端无需额外配置

Feign 自动传播 TraceId:feign-micrometer会在每次 Feign 请求的 Header 中自动注入traceparent(W3C 标准格式)。

5.3.5 启动 Zipkin Server

# Docker 方式dockerrun-d-p9411:9411 openzipkin/zipkin# 或下载 jarcurl-sSLhttps://zipkin.io/quickstart.sh|bash-sjava-jarzipkin.jar

5.3.6 验证

访问 Consumer → Provider → 打开http://localhost:9411→ 点击"Run Query":

Trace: 5f7a3b2c1d4e... ├── cloud-consumer-order-openfeign: 5ms │ └── cloud-payment-service: 62s ← 一眼定位! └── Total: 62s

5.4 深入原理

5.4.1 Trace 传播机制

Consumer Provider │ │ │ GET /feign/micrometer/1 │ │ Header: traceparent: │ │ 00-abc123-def456-01 │ │ ──────────────────────────────→ │ │ │ 提取 TraceId=abc123 │ │ 创建新 Span,parentSpanId=def456 │ │ │ ← 200 OK │ │ │ ├→ 上报 Span(consumer-side) → Zipkin └→ 上报 Span(provider-side) → Zipkin

W3C Trace Context 标准 Header

traceparent: 00-{trace-id}-{parent-span-id}-{trace-flags} │ │ │ └─ 01=采样 │ │ └─ 父 Span ID │ └─ 全局 Trace ID(32位hex) └─ 版本号(当前为 00)

5.4.2 采样策略

策略配置效果
Always全部采样probability: 1.0开发环境、排查问题
Probability按比例probability: 0.1生产环境,10% 采样
RateLimit每秒N条需自定义 Sampler按秒限制总条数
Never不采样probability: 0关闭追踪
// 自定义采样器 Bean@BeanpublicSamplerFunction<HttpRequest>mySampler(){returnrequest->{// 健康检查接口不采样if(request.path().startsWith("/actuator"))returnfalse;returntrue;};}

5.5 对比分析

维度SleuthMicrometer Tracing
Spring Boot 版本2.x3.x
底层 APIBrave/OpenTelemetryObservation API 统一抽象
配置前缀spring.sleuth.*management.tracing.*
日志 MDC自动注入 TraceId/SpanId需手动配置logging.pattern.level
Feign 集成spring-cloud-sleuthfeign-micrometer
未来方向停止维护Spring 主推

5.6 面试题

Q1:Sleuth 和 Micrometer Tracing 的核心区别?

  1. Sleuth 仅用于 Spring Boot 2.x,Micrometer Tracing 用于 3.x。
  2. Micrometer Tracing 使用 Observation API 统一了 metrics/tracing/logging 三个维度。
  3. 配置前缀从spring.sleuth.*变为management.tracing.*
  4. Micrometer Tracing 是 Spring 官方的长远方向。

Q2:TraceId 是如何跨服务传播的?

:通过 HTTP Header 传播。Feign 自动在请求中添加traceparent(W3C 标准)或X-B3-TraceId等 Header,下游服务从 Header 中提取 TraceId,创建子 Span。

Q3:高并发场景下如何平衡链路追踪的性能开销?

  1. 降低采样率:生产环境设为 0.010.1(1%10%)
  2. 使用异步上报:Zipkin Reporter 默认异步,不阻塞业务线程
  3. 配置 Span 数量上限:单个 Trace 最多创建 N 个 Span
  4. 使用消息队列缓冲:Zipkin → Kafka → Zipkin Server

5.7 踩坑指南

现象原因解决
🔴 配置不生效Zipkin 收不到数据Spring Boot 3.x 配置前缀从spring.zipkin改为management.zipkin检查配置路径
🔴 Feign 不传播 TraceIdZipkin 中 Consumer 和 Provider 是两条独立的 Trace缺少feign-micrometer依赖必须引入 6 个依赖中的第 5 个
🔴 采样率 1.0 导致 OOMZipkin 内存爆炸生产环境全量采样产生海量 Span生产设为 0.1
🔴 Zipkin 端口冲突Zipkin 启动失败9411 端口被占用换端口或 kill 占用进程

5.8 章节总结

要点说明
核心概念Trace(全局链路)+ Span(每个节点)+ Propagation(跨服务传递)
Sleuth→MicrometerSpring Boot 3.x 中 Sleuth 被取代,API 和配置前缀都变了
6 个依赖tracing + brave-bridge + observation + feign-micrometer + zipkin-reporter + tracing-bom
关键配置management.zipkin.tracing.endpoint+management.tracing.sampling.probability
Feign 自动传播feign-micrometer自动在 Header 中注入 W3C 标准的traceparent
采样率开发 1.0,生产 0.01~0.1

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询