← 返回题目列表

TraceId、SpanId 和 Span 分别是什么?

高频 中等 第 13 / 26 题 更新于 2026/07/28
TraceIdSpan链路追踪分布式追踪

简化版

TraceId 标识一次完整请求链路,Span 表示链路中的一个操作单元,比如一次 HTTP 调用、一次 SQL 查询或一个消息消费过程,SpanId 是 Span 的唯一标识。多个 Span 通过父子关系组成一棵调用树,共同描述一次请求从入口到结束的完整路径。

面试里可以说:TraceId 用来串起整次请求,Span 用来描述请求中的每一段工作,SpanId 和 ParentSpanId 用来还原调用关系。

详细版

一次请求进入网关时,追踪系统通常生成 TraceId。这个 TraceId 会随着请求在服务之间传播,后续服务创建自己的 Span,并记录操作名、开始时间、结束时间、耗时、状态、标签和事件。每个 Span 都有 SpanId,并通过 ParentSpanId 指向上游 Span。

例如一次下单请求的 Trace 可能包含:网关接入 Span、订单服务处理 Span、库存服务扣减 Span、数据库更新 Span、消息发送 Span。查看 Trace 时,工程师可以看到每段耗时和错误位置,从而定位瓶颈。

TraceId 也常写入日志 MDC,这样日志和链路追踪可以互相跳转。排查问题时,先从日志里找到 TraceId,再打开追踪系统看完整调用链,是非常常见的流程。

完整版教学

一、Trace 是一次完整请求

Trace 可以理解为一次请求在分布式系统中的完整足迹。用户发起一次下单,请求可能经过多个服务,但它们都属于同一个 Trace。

TraceId 是这次足迹的唯一编号。只要日志、调用链和错误事件都带上同一个 TraceId,工程师就能把散落在多个服务里的信息串起来。

TraceId 的价值不在于它本身有多复杂,而在于它能跨服务传播并保持一致。

二、Span 是一次局部操作

Span 是 Trace 中的一个片段。它表示某个服务或组件完成的一段工作。常见 Span 包括:

  1. 网关处理请求。
  2. 服务方法执行。
  3. HTTP 或 RPC 调用下游。
  4. SQL 查询或更新。
  5. Redis 命令。
  6. MQ 发送或消费。

每个 Span 通常会记录开始时间、结束时间、耗时、状态、操作名、服务名、实例信息和标签。

三、SpanId 和 ParentSpanId 还原调用树

只有 TraceId 还不够,因为它只能说明这些操作属于同一次请求,不能说明谁调用了谁。SpanId 标识当前 Span,ParentSpanId 标识它的父 Span。

例如:

TraceId = T1
Span A: 网关处理请求
  Span B: 订单服务处理
    Span C: 调用库存服务
    Span D: 写订单数据库

通过父子关系,追踪系统可以画出调用树和时间线,让人看到请求的结构。

四、Span 里常见字段

一个 Span 通常包含:

  1. traceId:所属 Trace。
  2. spanId:当前 Span 标识。
  3. parentSpanId:父 Span 标识。
  4. name:操作名,如 HTTP GET /orders
  5. startTime / endTime:开始结束时间。
  6. duration:耗时。
  7. status:成功、错误、超时等。
  8. attributes/tags:服务名、URL、SQL 表名、错误码等。
  9. events/logs:某些关键时间点事件。

这些字段越规范,追踪系统越容易聚合分析。

五、为什么 Span 不能随便打

如果每一行代码都创建 Span,链路会极其庞大,性能和存储成本都难以接受。Span 应该围绕有排障价值的边界创建,比如服务入口、远程调用、数据库访问、消息发送和关键业务步骤。

Span 太少,定位不到细节;Span 太多,噪音和成本会爆炸。生产系统要根据链路重要性和成本选择合理粒度。

六、TraceId 和日志的关系

日志通常会把 TraceId 放入 MDC 或类似上下文中,打印到每一行日志。这样从错误日志可以找到 TraceId,再进入追踪系统查看完整链路;也可以从追踪系统中的某个 Span 跳到对应服务日志。

这就是可观测性的关联能力。TraceId 不是只服务追踪系统,它也是日志、指标和告警之间的连接线。

七、面试回答建议

回答时先说 TraceId 标识一次请求,Span 表示一次操作,SpanId 标识 Span,ParentSpanId 表示父子关系。然后举一个下单请求跨网关、订单、库存、数据库的例子。

再补充 Span 记录耗时、状态、标签,TraceId 写入日志用于关联。这样答案既有概念,也有落地。

八、常见追问和落地边界

常见追问是 Span 粒度如何选择。服务入口、远程调用、数据库访问、消息发送这类边界通常值得建 Span;普通 getter、循环内部小函数不适合都建 Span。粒度过粗定位不到问题,粒度过细会造成噪音和成本。

另一个边界是 Span 标签不要乱加。URL、状态码、服务名、错误码有价值;订单号、用户 ID、TraceId 这类高基数字段不适合大量作为指标化标签。需要查询具体请求时,可以放日志或事件中,并注意脱敏。

九、常见误区与追问

这道题要紧扣「TraceId 与 Span」本身回答,不能把它混成泛泛的可观测性套话。面试官通常会沿着“为什么需要、流程怎么走、失败怎么兜、代价是什么”继续追问,所以回答要覆盖日志、指标、追踪、上下文传播、采样、告警和排障闭环。

回答层次要讲清的内容容易漏掉的边界
核心结论TraceId 标识一次完整请求,Span 标识其中一个调用或操作片段,父子关系组成链路树不要停在名词解释
流程机制入口生成 TraceId -> 创建根 Span -> 调用下游创建子 Span -> 传播 parent 信息 -> 记录耗时状态 -> 后端重建链路树要说清触发点、状态变化、确认点和失败兜底
工程取舍一次请求 TraceId 不变,网关、订单、库存各自创建 Span,SpanId 不同但 parent 指向上游可观测性不能替代稳定性设计,它用额外采集、存储和分析成本换更快定位问题
TraceId 与 Span 面试拆解:
1. 入口生成 TraceId
2. 创建根 Span
3. 调用下游创建子 Span
4. 传播 parent 信息
5. 记录耗时状态
6. 后端重建链路树

记忆钩子:先给结论,再拆流程,再讲数字例子和失败边界;回答「TraceId 与 Span」时要围绕题目问法收束,不要把相邻概念堆成一段没有重点的名词清单。

  • 误区:TraceId 和 SpanId 是同一个东西。 TraceId 串整条链路,SpanId 标识单个操作。
  • 误区:Span 越多越好。 过细会增加采集成本和噪声,要围绕关键边界埋点。
  • 误区:TraceId 只能用于链路系统。 它也应进入日志和错误事件,用于跨系统检索。
  • 追问:根 Span 是什么? 一次请求入口创建的第一个 Span,表示整条请求的起点。
  • 追问:父子 Span 有什么用? 还原调用层级和耗时归属,定位等待发生在哪一段。
  • 追问:异步任务怎么建 Span? 从消息或任务上下文恢复 Trace,再创建新的 consumer/internal Span。

十、加强记忆

TraceId 像一次旅行的行程号,Span 像行程中的每一段路,SpanId 是每段路的编号,ParentSpanId 说明这段路是从哪一段接下来的。

链路追踪就是把这些路段拼起来,看一次请求到底走过哪里、哪里慢、哪里错。