第63章|可观测性 3:分布式追踪(Tracing)与性能定位

指标告诉你“系统变慢了”,日志告诉你“哪里报错了”,而追踪会告诉你“这次请求到底走了哪条路、卡在了哪一跳”。 当服务链路越来越长,Tracing 就像给每个请求安装 GPS:你能看到跨服务耗时、重试风暴、N+1 查询和下游抖动如何层层放大。

Model

trace / span

  • parent-child graph
  • duration + status
  • attributes/events
Tooling

OTel pipeline

  • SDK instrumentation
  • collector processing
  • Jaeger / Tempo backend
Use

Perf triage

  • critical path
  • tail latency source
  • release regression diff

1. Trace 与 Span:请求的“时间拓扑图”

一个 trace 代表一次端到端请求;每个 span 代表请求中的一个步骤(HTTP 调用、SQL 查询、缓存访问等)。 span 之间的父子关系会形成树或有向图。排障时最重要的是找到 critical path:决定总耗时的关键链路。

Trace topology (single request) API Gateway span (root) auth-service span order-service span db query span critical path: gateway → order-service → db query tail latency often hides here
图 1:trace 让你看到请求的“结构”和“耗时传播路径”。

2. OpenTelemetry 数据路径:SDK → Collector → Backend

现代追踪通常以 OpenTelemetry 为标准:应用侧 SDK 采集 span,发送到 OTel Collector,经过处理再写入 Jaeger/Tempo 等后端。 Collector 可以做采样、属性清洗、租户路由和批处理,避免应用直接耦合具体后端。

# OTel Collector (illustrative)
receivers:
  otlp:
    protocols:
      grpc:
      http:

processors:
  batch:
  tail_sampling:
    policies:
      - name: error_traces
        type: status_code
        status_code:
          status_codes: [ERROR]

exporters:
  otlp/tempo:
    endpoint: tempo.monitoring.svc:4317

service:
  pipelines:
    traces:
      receivers: [otlp]
      processors: [batch, tail_sampling]
      exporters: [otlp/tempo]
OTel trace pipeline service A SDK service B SDK OTel Collector batch / sampling / routing Tempo trace backend
图 2:Collector 是追踪体系的“中枢神经”,隔离应用与后端实现。

3. 采样策略:既要看见问题,也要控制成本

全量追踪在高流量场景成本很高。常用策略是基础概率采样 + 错误优先保留(tail sampling)。 换句话说:成功请求抽样看趋势,错误/超时请求尽量保留看细节。

StrategyBest forRisk
Head samplinglow overhead baselinemay miss rare failures
Tail samplingerror/latency-focused debuggingcollector complexity
Adaptive samplingcost-aware dynamic trafficharder to reason consistency
底线:错误请求和慢请求要“高保真保留”,否则 tracing 只会告诉你“系统大概没问题”。

4. 发布回归定位:把 trace 和 release marker 绑在一起

当某次发布后 p99 上升,最快的定位方式是按 release_id 对比前后 trace 分布: 哪个 span 的耗时分位点变化最大?是否出现新的下游调用?是否重试次数增加? 这能把“感觉变慢”变成“第 N 跳新增 80ms”的可行动结论。

# Pseudocode idea: compare span latency distributions by release_id
before = query_spans(service="checkout", release_id="rel-120")
after  = query_spans(service="checkout", release_id="rel-121")
diff = compare_p99_by_span(before, after)
print_top_regressions(diff)
Trace regression diff by release span: gateway +8ms span: inventory +46ms span: payment +92ms (critical) span: db +68ms
图 3:按 release_id 对比 span 分位点,能快速锁定回归源头。

5. 落地反模式与实践建议

建议:先覆盖“最关键用户路径”的追踪,再逐步扩展到边缘流量;优先保证链路完整性和字段一致性。

6. 本章清单

  1. 理解 trace/span 模型,并能在图中识别 critical path。
  2. 完成 OTel 基础链路:SDK → Collector → Backend。
  3. 设计采样策略:成功请求抽样 + 错误请求高保留。
  4. 实现 trace_id 跨服务透传,保证链路不丢。
  5. 将 release marker 与 tracing 关联,用于发布回归定位。
  6. 预告下一章:SRE 基础(错误预算、变更管理与可靠性交付)。
← 上一章:可观测性 2 下一章:SRE 基础 →