W3C Trace Context 标准
在 OpenTelemetry 出现之前,各追踪系统使用各自独立的 Context 传播协议:Jaeger 使用 uber-trace-id,Zipkin 使用 b3,AWS X-Ray 使用 x-amzn-trace-id。这种碎片化导致不同追踪系统之间的 Context 无法互通——从 Jaeger 采集的请求,传递到 Zipkin 后会丢失 TraceID。
W3C Trace Context 是解决这个问题的标准规范。它由 W3C 分布式追踪工作组制定,定义了跨进程传播追踪上下文的统一格式。目前,所有主流追踪系统(Jaeger、Zipkin、AWS X-Ray、Datadog)都已支持 W3C Trace Context。
traceparent Header
traceparent 是 W3C Trace Context 的核心 Header,格式为:
四个字段用 - 分隔:
版本号(Version):2 个十六进制字符,当前是 00。用于未来协议升级。
TraceID:32 个十六进制字符,标识整个请求的唯一 ID。TraceID 的全局唯一性由���口服务生成。
ParentID / SpanID:16 个十六进制字符,标识当前操作的 ID。每个服务在发送请求时生成自己的 SpanID,作为下游的 ParentID。
Trace Flags:2 个十六进制字符,当前只定义了一个标志位(采样位)。01 表示已采样,00 表示未采样。
tracestate Header
tracestate 用于携带供应商特定的状态信息,格式为键值对列表:
tracestate 的设计允许不同追踪系统共存。例如,congo 是 Jaeger 的厂商键,rojo 是 Zipkin 的厂商键。如果请求先经过 Jaeger 采集,再传递到 Zipkin,两者的状态都可以保留。
采样决策的传播
traceparent 的 Trace Flags 字段用于传播采样决策。当入口服务决定不采样(丢弃请求的追踪数据),Trace Flags 设为 00;下游服务看到这个标志后,应该也不采样,避免产生无用的追踪数据。
这种设计确保了:如果入口未采样,整个调用链都不会产生追踪数据,不会浪费存储资源;如果入口已采样,所有下游服务都会产生追踪数据,保留完整的调用链。
OpenTelemetry 的支持
OpenTelemetry SDK 原生支持 W3C Trace Context。在 Java SDK 中,配置 propagator:
SDK 会自动将 traceparent 和 tracestate 注入到 HTTP Header 中,并在接收请求时自动提取。