分布式追踪

用 trace/span 结构记录跨服务调用链:一次请求一个 trace,每个处理单元一个 span,记录耗时与父子关系;是定位跨服务延迟与失败传播的主要手段。

分布式追踪记录什么

分布式追踪用 trace 与 span 两级结构记录一次请求的完整路径:一个请求对应一个 trace,每个处理单元(一次 RPC、一次数据库查询、一段本地计算)对应一个 span,span 记录起止时间、耗时、状态与父子关系。它把“这段延迟花在哪里”从猜测变成可测量的数据,是定位跨服务延迟与失败传播的主要手段。上下文传播是它的前提——trace ID 与 span ID 必须跨进程、跨线程传递。

基本信息

术语Trace(一次请求)、Span(处理单元)、上下文传播
采样头部采样或尾部采样,权衡成本与代表性
使用先看最长子路径,再看错误标记与重试次数
标准OpenTelemetry 定义数据模型与传播格式,后端可替换

典型使用场景

  • 跨服务延迟定位:确认一次慢请求在哪个服务、哪次调用上耗时超标
  • 错误传播分析:找出哪一跳最先失败,以及重试发生在哪里
  • 依赖关系梳理:从调用数据中发现未被文档记录的隐性依赖
  • 容量与热点分析:按接口与下游统计耗时分布,指导优化排序
  • 发布验证:对比发布前后同类请求的耗时构成变化

采样策略对照

策略机制适用
头部采样入口按比例决定,链路内一致常规流量
尾部采样收集完整后按规则决策错误与慢请求留存
关键路径全量指定接口全量记录核心链路排查
按调用方采样按租户或应用差异化采样率重点客户与试点环境

一次请求的 span 结构

一次请求的 span 结构
trace_id = 7f3a... (全局唯一,HTTP 头与消息属性透传)
├─ span 网关            12ms
├─ span 订单服务http    145ms
│   ├─ span 库存查询     38ms
│   └─ span MySQL 写入   62ms   ← 本次请求耗时最长的一跳
└─ span 支付服务http     55ms
# 先看父子关系与耗时排序,再看状态码与重试标记

使用要点

  • 采样率要能覆盖故障场景:常规低采样配合错误与慢请求全量留存,避免出事时样本不足
  • 上下文传播要覆盖异步与线程池:消息属性、任务提交与回调都要显式恢复上下文
  • span 命名保持稳定:用接口与服务名而不是包含参数的动态字符串,否则聚合分析失效
  • 把追踪数据与指标、日志关联起来:用同一 trace ID 跳转,减少在多个系统之间来回查找
  • 控制数据量:设定采样率与保留策略,关键错误路径可以全量留存
追踪数据量大:设定采样率与保留策略,关键错误路径可以全量留存,避免因为成本把采样率压到出事时看不到样本。
异步、线程池与消息消费是上下文丢失的高发区:这些位置缺少上下文时,链路会在追踪系统里断开,看起来“没有问题”的短链路往往正是丢失的位置。

易错点

  • 异步与线程池丢失上下文,链路断开,最需要排查的异步段反而没有数据
  • 采样率过低,故障期间没有代表性样本,只有统计指标没有细节
  • span 命名带参数(如包含订单号),基数爆炸导致后端存储与聚合查询都不可用
  • 只在入口埋点不记录内部关键调用,看到总耗时但看不出瓶颈在哪里
  • 追踪与日志各自独立,缺少统一的 trace ID 关联,排查要在多系统间手工比对时间戳

数据来源与参考

  • OpenTelemetry 文档:Traces
  • Google Dapper 论文(2010)
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌