Tempo 系统需搭配 OpenTelemetry 采集、OTel Collector 传输、Grafana 查询,TraceID 贯穿是关键:HTTP 头传 traceparent、异步任务手动注入、跨语言统一 W3C;本地用 docker-compose 5 分钟验证,生产需采样、打标、权限管控与健康监控。

直接用 Docker Compose 搭一套轻量但可用的 Tempo 系统,配合 OpenTelemetry 上报和 Grafana 查看,就能完成请求链路溯源。关键不是堆功能,而是让 TraceID 能贯穿、能查到、能关联日志和指标。
选对组件组合,避免过度设计
Tempo 本身不采集、不渲染、不索引全字段,它只做一件事:按 TraceID 存和取。所以必须搭配其他工具才能形成完整链路:
- 采集端:统一用 OpenTelemetry SDK(支持 Go/Python/Java 等),通过 OTLP 协议发数据,避免 Zipkin/Jaeger SDK 混用导致上下文丢失
- 传输层:部署 OpenTelemetry Collector,做协议转换、采样、标签增强,再转发给 Tempo
-
存储后端:本地开发用
local模式(存到 /tmp/tempo-data);生产环境建议配 S3 或 MinIO,低成本且易扩展 - 查询入口:Grafana 内置 Tempo 数据源,无需额外部署 Jaeger UI;开启 Exemplars 后还能从 Prometheus 指标一键跳转到对应 Trace
快速启动本地验证环境
不需要 Kubernetes 或复杂配置,5 分钟跑起来验证链路是否通:
- 新建
docker-compose.yml,包含tempo、grafana和otel-collector三个服务 - Tempo 配置里明确启用 OTLP 接收器(默认监听
0.0.0.0:4317),并指向本地块存储路径 - Grafana 中添加 Tempo 数据源,地址填
http://tempo:3200(Docker 内网互通) - 运行
docker compose up -d,访问localhost:3000,在 Explore → Tempo 中输入 TraceID 就能查到完整调用树
确保 TraceID 真正贯穿整个请求
链路断掉,90% 是上下文传递没做好。重点检查这几个环节:
- HTTP 请求头必须携带
traceparent(W3C 标准格式),OpenTelemetry 默认自动注入,但中间件如 Nginx、API 网关可能过滤掉,需显式放行 - 异步任务(如消息队列消费、定时任务)要手动将父 SpanContext 注入新 Context,否则会生成新 TraceID
- 跨语言服务间调用,确认双方都用 OTLP + W3C 传播,避免 B3 和 TraceContext 混用导致解析失败
- 在 Grafana 的 Logs 或 Metrics 视图中点击某个日志条目或指标异常点,看能否通过 Exemplars 自动带出 TraceID 并跳转——这是验证“三位一体”是否生效的最直接方式
生产环境需加固的关键点
本地跑通只是第一步,上线前注意这些实际影响溯源效果的细节:
- 设置合理采样率:全量上报压力大,建议用 Collector 的
probabilistic采样(如 1%),对错误 Span 强制 100% 保留 - 为 Span 添加业务属性:比如
http.route、service.version、user.id,方便后续在 Grafana 中按维度筛选 - 对象存储权限最小化:Tempo 只需读写 blocks 目录,不要给 root 权限;wal 目录用于崩溃恢复,也需独立挂载
- 监控 Tempo 自身健康:检查
/metrics中tempo_distributor_span_received_total是否持续增长,tempo_ingester_block_duration_seconds是否超长,避免数据积压


















