Tempo服务端必须暴露gRPC和HTTP接口,默认仅监听127.0.0.1,需改为0.0.0.0;Go客户端须用tempo-go SDK而非原生OTLP exporter;生产环境必须配置对象存储并启用compactor;采样率需与distributor对齐,避免资源耗尽。

Tempo 服务端配置必须暴露 gRPC 和 HTTP 接口
Tempo 默认只监听本地 127.0.0.1:9095(gRPC)和 127.0.0.1:3200(HTTP),Golang 组件若部署在不同 Pod 或机器上,会直接报 connection refused 或 context deadline exceeded。必须显式绑定到 0.0.0.0:
- 修改
tempo.yaml中的server.http_listen_address为0.0.0.0:3200 - 同理设置
server.grpc_listen_address: 0.0.0.0:9095 - 若用 Docker/K8s,确认容器端口已正确
expose,且 Service 的targetPort对应 gRPC 端口(不是 HTTP 端口)
Go 客户端必须用 tempo-go SDK 而非原生 OTLP exporter
官方 go.opentelemetry.io/otel/exporters/otlp/otlptrace 默认发 OTLP/gRPC 到 localhost:4317,但 Tempo 的 OTLP 接收器默认未启用——它只认自己的 tempo-distributor 协议或 Jaeger/Zipkin 格式。直接连会返回 rpc error: code = Unimplemented desc = unknown service otlp.collector.v1.TraceService。
- 改用
github.com/grafana/tempo-goSDK,它封装了 Tempo 原生 gRPC trace 上报逻辑 - 初始化时指定
tempo-go.NewClient(tempo-go.WithAddress("tempo-distributor:9095")),地址指向 distributor(非 querier) - 注意:该 SDK 不支持 span 属性自动注入 service.name,需手动调用
span.SetAttributes(attribute.String("service.name", "my-service"))
海量 Trace 存储依赖后端对象存储,不能只靠本地文件
Tempo 单机模式下用 local storage(如 boltdb + filesystem)仅适合调试;一旦 trace QPS 超过 50/s 或保留周期 > 7 天,写入延迟飙升、OOM 频发。
使用 uber-go/dig 在 Golang 中实现依赖注入——基于反射容器,提供 Provide/Invoke、dig.In/dig.Out 参数与结果对象,支持命名依赖等
- 生产必须配对象存储:S3 兼容(
s3)、GCS(gcs)或 Azure Blob(azure) - 关键配置项:
storage.backend: s3+storage.s3.bucket: "my-tempo-traces"+storage.s3.endpoint: "s3.us-east-1.amazonaws.com" - 务必开启
compactor.enabled: true,否则 S3 上碎片化 block 文件堆积,查询变慢且成本翻倍
Go 组件中采样率必须与 Tempo distributor 对齐
Tempo 的 distributor 默认全局采样率为 1(全量),但 Go 应用若用 otel/sdk/trace 自定义采样器(如 trace.AlwaysSample()),会导致 trace 数量远超 distributor 承载能力,出现 rpc error: code = ResourceExhausted desc = grpc: received message larger than max (4194304 vs. 4194304) 或 HTTP 429。
- 推荐方案:关闭 Go 端采样,交由 Tempo 统一控制,在
tempo.yaml中设metrics_generator.pipelines[0].processors[0].sampling.rate: 0.01 - 若需按 service 动态采样,用
tempo-go的WithSamplingRate(0.001)初始化 client,值必须 ≤ distributor 允许的最大速率 - 验证方式:查 Tempo metrics
tempo_distributor_received_spans_total{job="tempo-distributor"}是否稳定,突增即说明采样不匹配
真正麻烦的是 block 压缩参数和 retention 策略——它们不写进 Go 代码,全靠 Tempo 配置生效,改错一个字段就导致 trace 查不到或磁盘爆满。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










