文章

分布式追踪 OpenTelemetry

分布式追踪:OpenTelemetry 与 Jaeger/Tempo

一句话:当一次请求穿过 7 个微服务,Metrics 告诉你”慢了”,Logs 告诉你”某个服务报错了”,但只有 Trace 能告诉你”时间花在哪一段、哪次调用最慢”。Trace 是请求视角的时延分解。

核心概念

概念含义
Trace一次完整请求的所有 span 组成的树
Spantrace 中的一个操作单元(一次 RPC、一次 DB 查询),有起止时间
Context携带 trace_id + span_id 的上下文,跨进程传递
Propagation把 context 注入/提取出请求头(W3C traceparent
ExemplarHistogram 样本挂一个 trace_id,实现指标→trace 下钻

OpenTelemetry 架构

graph LR
    APP[应用 + OTel SDK] --> INJ[注入 traceparent]
    APP --> COL[OTel Collector]
    COL --> J[(Jaeger)]
    COL --> T[(Tempo)]
    COL --> P[(Prometheus)]
    SVC2[下游服务] --> EX[提取 context] --> COL
  • SDK:自动(auto-instrumentation,如 Java agent / Python 包)或手动埋点,产生 span
  • Collector:接收(OTLP)→ 处理(batch/采样/过滤)→ 导出(backend)
  • Backend:Jaeger / Tempo / Zipkin 存 trace、提供查询 UI

OTel 的关键价值:instrumentation 与 backend 解耦。代码只依赖 OTel API,换 Jaeger 还是 Tempo 只改 Collector 配置,不碰业务代码。

Context Propagation(跨进程的关键)

没有 context 传递,每个服务各生成自己的 trace,链就断了。

上游: traceparent: 00-<trace_id>-<span_id>-01
  → HTTP header 传给下游
下游: 提取 traceparent → 新建 child span(parent=上游 span_id)
  • W3C traceparent 是跨语言标准(HTTP/gRPC 头)
  • baggage 可携带业务上下文(如 user_id)跨服务
  • 你的 Envoy 与 Nginx 对比 里 Envoy 天然支持注入/提取 trace header(L7 代理优势),所以 Cilium+Envoy sidecar 能自动串起 trace。

采样策略

全采成本爆炸,常见策略:

策略说明适用
Head sampling请求一开始就决定是否采(随机 1%)基础,便宜
Tail-based sampling看完整个 trace 再决定(错误/慢请求必采)生产推荐(Collector 尾采样)
Rate limiting每秒最多采 N 条防突发

Tail-based 是生产中”既要省钱又要抓异常”的标配——错误和慢请求 100% 采,正常请求抽稀。

Jaeger vs Tempo

JaegerTempo(Grafana)
存储Cassandra/ES 自有模型对象存储 + 索引极小(靠 trace_id 查)
定位老牌、功能全与 Loki/Prometheus 同生态、极便宜
查询自有 UIGrafana 内统一查

与你的 vault 强相关:Cilium Hubble

Hubble 的 flow 观测本质就是基于 Envoy 的分布式追踪 + 网络层可见性:

  • Envoy sidecar 生成/传播 trace(见 Envoy 与 Nginx 对比
  • Hubble 把每个网络流(哪个 Pod→哪个 Pod、哪个 L7 请求、被 Policy 放行/拒绝)作为可观测事件
  • 在 Grafana 里 Hubble flow + Jaeger trace 可关联排查”服务慢是因为网络策略丢了包还是下游慢”

关联知识

参考资源

学习时间

内容日期状态
分布式追踪 OTel2026-07-24完成:trace/span、OTel 架构、propagation、采样、Jaeger/Tempo、Hubble 关联

状态

  • 核心概念
  • OTel 架构
  • Context Propagation
  • 采样策略
  • Jaeger vs Tempo + Hubble 关联