1365 字
约 4 分钟
10
S16-J01 · 链路追踪基础:Trace / Span / Parent Span
2024-12-31
2026-11-07

适用读者:微服务排障时靠"挨台机器看日志"的人。
前置:S16-B03(集成测试)、S02(HTTP 基础)、S17(微服务雏形)。
覆盖旧文:A-560 → 143 点(§1 为什么需要链路追踪、§2 Trace 与 Span、Parent Span、Zipkin/Sleuth 定位)。
扩展点:E-S16-005(Trace 与 Span 的边界)。
上一篇:S16-B04 · 端到端:跑通完整流程才算真正验证
下一篇:S16-J02 · Spring Boot 3 接入实战。


1. 一句话结论

链路追踪解决的是"同一次请求在 N 个进程里的身份问题"。 它不告诉你"哪里慢",但它告诉你"这 8 秒的 8 个片段分别属于谁"——慢的定位是从这里开始的。

单体时代 微服务时代
一个日志文件里搜一次请求 5 台机器、5 个日志文件,靠 traceId 串起来
看堆栈就知道调用链 调用链本身要被记录才存在

2. 三个概念,一句话各自定义(A-560)

概念 定义 类比
Trace 一次完整请求的生命周期,由一个 traceId 标识 快递单号
Span 请求中的一个操作片段(一次 RPC、一次 SQL、一次缓存访问) 中转站扫描记录
Parent Span 当前 span 的上游调用者;决定 span 树的形状 上一站
TraceId = af27c910...

Gateway    (spanId=001, parent=null)
└── Order  (spanId=002, parent=001)
    ├── MySQL      (spanId=003, parent=002)
    ├── Redis      (spanId=004, parent=002)
    └── Payment    (spanId=005, parent=002)
        └── HTTP   (spanId=006, parent=005)  → 第三方支付

判据:拿到一个 traceId,能不能在 UI 里还原出这棵树?能 → 埋点正确;只能看到零散记录 → 上下文没传播(J02)。


3. Trace 与 Span 的边界(E-S16-005)

新手最容易犯的错是"什么都建 span",导致树爆炸、开销上升。判据三条:

该新建 span 不该新建
跨进程调用(HTTP/RPC/MQ) 同类内部的小函数调用
I/O 边界(SQL、Redis、文件、外部 API) 纯计算(用 profiling 看,不用 span)
有明显耗时或失败可能的阶段 循环里的每次迭代(用 span 的 attribute 记次数)

经验值:一次请求 10–50 个 span 属正常;上千个说明建错了层级。


4. 上下文传播:traceparent 到底传了什么

W3C Trace Context 规定的标准头(跨语言、跨厂商的事实标准):

traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01
             ┬─ ───────────────┬─────────────── ────────┬────── ─┬
             │                 │                        │        └ flags(01=采样)
             │                 │                        └ parent-id(16 hex)
             │                 └ trace-id(32 hex)
             └ version
传播载体 场景
HTTP header(traceparent/tracestate) 服务间调用
MQ message headers 异步链路(否则链路在此断掉)
日志 MDC 让日志能按 traceId 聚合(J02 §5)

判据:跨线程/跨进程/跨 MQ 之后,traceId 是否还一样? 任何一处断了,后面的调用就是"孤儿 span"。


5. 三个组件各管什么(原文的定位)

组件 角色 现状(2026)
Zipkin 追踪后端 + UI:收 span、存、查 仍在维护,轻量、适合学习与中小规模
Sleuth Spring Cloud 的追踪自动配置(生成/传播 traceId) Spring Boot 3 起不再演进,被 Micrometer Tracing 取代
Micrometer Tracing Boot 3 的追踪门面,桥接 Brave / OpenTelemetry 当前推荐(J02)
OpenTelemetry 厂商中立的 API/SDK/协议(OTLP) 跨语言首选;与 Zipkin 可互通

为什么必须说清这层:大量旧文写"加 spring-cloud-starter-sleuth 即可",在 Boot 3 上根本拉不起来——这是版本陷阱,J02 会给出正确依赖。


6. 一个最小的心智模型:追踪 = 结构化日志 + 树

Span 的字段(最小集):
  traceId / spanId / parentId
  name(操作名,如 "GET /orders/{id}")
  startTime / duration
  status(OK / ERROR)/ error 信息
  attributes(http.method、db.statement、peer.service ...)

判断"这个系统适不适合上追踪"(A-560 §14 的四场景,任务版):

场景 建议
单体 + 单库 结构化日志足够,追踪收益低
3 个以上服务互相调用 值得上,排障收益立刻可见
只在学分布式概念 用 Zipkin + 两个服务即可,别上全套
已有 Prometheus 指标 追踪补"跨服务因果",两者互补

7. 常见误区

误区 纠正
"有日志就不需要追踪" 日志能证明"发生了什么",追踪证明"谁调用了谁、各花多久"
"traceId 打到日志里就够了" 还需要 span 的父子关系,否则无法定位耗时归属
"采样 100% 才准" 高流量下 1%–10% + 错误全采,足够定位(A01)
"追踪能替代 profiling" 追踪是跨进程视角,方法级热点要靠 profiling

8. 自测

  1. 画一次你熟悉的请求的 span 树(至少 5 个 span,标出 parent)。
  2. 你的异步任务(MQ/线程池)里,traceId 还在吗?不在 → J02 §5。
  3. 一次请求产生 800 个 span,最可能的原因是什么?

9. 下一篇

S16-J02 · 接入实战:Spring Boot 3 + Micrometer Tracing + Zipkin —— 给出能跑起来的依赖、配置、采样与"traceId 进日志"的完整步骤。

S16-J01 · 链路追踪基础:Trace / Span / Parent Span
https://www.clxhxhhr.top/posts/5410/
作者
clxstart
发布于
2024-12-31
许可协议
CC BY-NC-SA 4.0
评论
0 条
还没有评论,先写一条吧。