- 后端
- 可观测性
- 链路追踪
【免费下载链接】tempo
Grafana Tempo is a high volume, minimal dependency distributed tracing backend.
导读
本文围绕 OpenTelemetry Collector 仓库中 receiver/README.md 所定义的 Receiver 通用概念,结合 Grafana Tempo 的源码与示例配置,系统讲解 Receiver 如何在 traces/metrics/logs 管道中完成数据接入:包括receivers配置块的语法、命名规则、管道启用机制,以及 Tempo 在 modules/distributor/receiver 中如何以 OTLP、Jaeger、Zipkin、Kafka 四种 Receiver 直接接收分布式追踪数据的实战方案。读完本文,你将掌握在 Tempo 中配置与调试各类型 Receiver 的完整方法,并理解其底层数据流转原理。
Receiver 是什么:数据进入 Collector/Tempo 的入口
根据 receiver/README.md 的定义,Receiver 是数据进入 OpenTelemetry Collector 的入口。一般来说,Receiver 以指定格式接收数据,将其转换为内部格式,再传递给管道中定义的 processors(处理器)和 exporters(导出器)。
数据源 (SDK / Agent / 其他系统) │ 以 OTLP / Jaeger / Zipkin 等协议传输 ▼ Receiver ──► Processor(s) ──► Exporter (接收并转换为内部格式) (处理) (发送到后端)在 OpenTelemetry Collector 核心仓库中,官方托管的 traces、metrics、logs 管道通用 Receiver 为:
- OTLP Receiver——通过 gRPC 或 HTTP 接收 OTLP 格式数据,traces、metrics、logs 信号均达到 stable 稳定性等级;
此外,contrib 仓库提供了更多在其发行版中可用的 Receiver(如 Jaeger、Zipkin、Kafka 等),本文后续会看到这些 contrib Receiver 正是 Tempo 实际使用的主要来源。
Tempo 中的 Receiver 应用场景:distributor 模块的数据入口
虽然 Tempo 并非一个完整意义上的 OpenTelemetry Collector,但它借助 OpenTelemetry Collector 的组件体系,在distributor(分发器)模块中复用了 Receiver 机制来接收追踪数据。
在 Tempo 中,Receiver 配置位于顶层distributor配置下的receivers节点。源码 modules/distributor/config.go 中对此有明确注释:
This receivers node is equivalent in format to the receiver node in the otel collector.
即:Tempo 中distributor.receivers的格式与 OpenTelemetry Collector 的receivers节点完全等价,因此本文介绍的语法规则对两者均适用。
从 modules/distributor/receiver/shim.go 的源码可以看到,Tempo 目前注册的 Receiver 工厂包括:
| Receiver 类型 | 工厂来源 | 说明 |
|---|---|---|
otlp | otlpreceiver.NewFactory() | OTLP gRPC/HTTP,来自 collector 核心库 |
jaeger | jaegerreceiver.NewFactory() | Jaeger 协议,来自 contrib 库 |
zipkin | zipkinreceiver.NewFactory() | Zipkin 协议,来自 contrib 库 |
kafka | kafkareceiver.NewFactory() | Kafka 消息,来自 contrib 库 |
Tempo 默认只启用其中两个 Receiver(见 modules/distributor/config.go 的defaultReceivers):jaeger(grpc 与 thrift_http 协议)和otlp(grpc 协议)。这意味着不写任何receivers配置时,Tempo 也会默认监听 Jaeger gRPC 与 OTLP gRPC 端口。
Tempo 中 Receiver 的启动方式与 Collector 略有差异:它通过receiversShim将所有 Receiver 包装为一个services.Service,在 distributor 启动时一并启动、停止时统一关闭(见 shim.go),并为每种启用的 Receiver 记录使用统计指标(receiver_enabled_otlp、receiver_enabled_jaeger、receiver_enabled_zipkin、receiver_enabled_kafka)。
配置 Receivers:receivers顶层配置块语法
基本语法
Receivers 通过 YAML 在顶层receivers标签下配置。配置中必须至少启用一个 Receiver 才被视为有效配置。
以下示例来自 receiver/README.md,展示了两个 Receiver 实例的配置方式:
receivers: # Receiver 1。 # <receiver type>: examplereceiver: # <setting one>: <value one> endpoint: 1.2.3.4:8080 # ... # Receiver 2。 # <receiver type>/<name>: examplereceiver/settings: # <setting two>: <value two> endpoint: 0.0.0.0:9211语法要点:
- Receiver 类型:如
otlp、jaeger、zipkin、kafka,对应已注册的工厂; - 多实例命名:以
<receiver type>/<name>形式可创建同一类型的多个实例,例如examplereceiver/settings; - 全名唯一性:Receiver 的**完整名称(full name)**由
receiver type + '/' + name组成,所有 Receiver 的全名必须唯一。上例中 Receiver 1 全名为examplereceiver,Receiver 2 全名为examplereceiver/settings。
在 Tempo 中的实际位置:distributor.receivers
在 Tempo 中,这一配置块被嵌入到distributor之下。一个真实的最小示例来自 example/docker-compose/single-binary/tempo.yaml:
distributor: receivers: otlp: protocols: grpc: endpoint: "tempo:4317" http: endpoint: "tempo:4318"这里展示了 OTLP Receiver 同时开启 gRPC 与 HTTP 两种协议的配置方法,endpoint使用host:port形式指定监听地址。
在管道中启用 Receiver
Collector 中的管道引用
Receiver 在加入管道(pipeline)后才被启用。配置示例如下(来自 receiver/README.md):
service: pipelines: # 合法管道类型为: traces, metrics 或 logs # Trace 管道 1。 traces: receivers: [examplereceiver, examplereceiver/settings] processors: [] exporters: [exampleexporter] # Trace 管道 2。 traces/another: receivers: [examplereceiver, examplereceiver/settings] processors: [] exporters: [exampleexporter]要点:
- 管道通过 Receiver 的完整名称引用实例,例如
examplereceiver/settings; - 同一 Receiver 实例可以被多个管道共享引用;
- 每个管道必须至少启用一个 Receiver,否则配置无效。
Tempo 的管道接法
Tempo 没有像 Collector 那样暴露service.pipelines,而是将接收到的数据直接接入receiversShim。从源码 shim.go 可以看到,Tempo 内部会构造一个仅含receivers、exporters(nop占位导出器)与traces管道的 mock 配置交给 otelcol 解析,从而复用 Collector 的配置校验与 Receiver 创建逻辑——每个配置的 Receiver 都隐式地接入一条 traces 管道,其下游消费者就是 shim 本身。
当 Receiver 收到数据后,ConsumeTraces(见 shim.go)会执行以下关键动作:
- 从 context 中提取租户 ID(多租户场景);
- 调用
pusher.PushTraces将ptrace.Traces推送给 distributor 核心逻辑; - 记录
tempo_distributor_push_duration_seconds指标; - 若推送失败且错误码为
ResourceExhausted,根据配置的retry_after_on_resource_exhausted时长包装为带RetryInfo的可重试错误返回给客户端(默认 5 秒,见 modules/distributor/config.go)。
OTLP Receiver 详解
OTLP Receiver 通过 gRPC 或 HTTP 接收 OTLP 格式数据,是官方文档 otlpreceiver/README.md 中唯一在 collector 核心仓库托管的 Receiver,其 traces、metrics、logs 信号稳定性为 stable。
启用与协议
启用 OTLP Receiver 只需在 receiver 定义中包含它;未在protocols列表中指定的协议即被禁用:
receivers: otlp: protocols: grpc: http:各协议默认监听端口:
| 协议 | 默认 endpoint |
|---|---|
| gRPC | localhost:4317 |
| HTTP | localhost:4318 |
通过 HTTP/JSON 写入数据
OTLP Receiver 除 gRPC 外,还可通过 HTTP/JSON 接收导出调用,序列化格式需符合 OTLP JSON 编码规范。各信号类型的 URL 路径可分别通过traces_url_path、metrics_url_path、logs_url_path、profiles_url_path配置修改,默认值分别为/v1/traces、/v1/metrics、/v1/logs、/v1/profiles。
写入方式:向[address]/[traces_url_path]发送POST请求即可推送 traces。默认 HTTP 端口为4318。
CORS 配置
HTTP/JSON 端点支持在cors:下配置跨域策略(完整示例见 otlpreceiver/README.md):
receivers: otlp: protocols: http: endpoint: "localhost:4318" cors: allowed_origins: - http://test.com # Origin 支持 * 通配符,单独使用 * 表示匹配任意来源。 - https://*.example.com allowed_headers: - Example-Header max_age: 7200配置项说明:
allowed_origins:允许请求的来源(origin),支持通配符模式;allowed_headers:除默认安全列表外额外允许的请求头;max_age:浏览器缓存预检(preflight)响应的时长。
Tempo 中的 OTLP 配置实战
Tempo 的分布式追踪场景中,最常见的配置是同时开启 gRPC 与 HTTP 协议(见 example/docker-compose/distributed/tempo.yaml):
distributor: receivers: otlp: protocols: grpc: endpoint: "0.0.0.0:4317" http: endpoint: "0.0.0.0:4318"集成测试配置 integration/operations/config-receivers.yaml 也印证了这一典型形态。
多租户支持:从源码 shim.go 可以看到,当 OTLP Receiver 启用 HTTP 协议时,Tempo 会自动设置IncludeMetadata = true,确保 HTTP 请求头(如X-Scope-OrgID)被注入 context,这是多租户认证的前提;gRPC 场景则由 middleware.go 中的MultiTenancyMiddleware负责从 gRPC 请求或 HTTP metadata 中提取租户 ID 并注入 context。
其他 Receiver:Jaeger、Zipkin 与 Kafka
除 OTLP 外,Tempo 还支持来自 contrib 仓库的三个 Receiver,均通过modules/distributor/receiver/shim.go注册:
Jaeger Receiver
Tempo 默认启用 Jaeger Receiver 的grpc与thrift_http协议。配置示例:
distributor: receivers: jaeger: protocols: grpc: endpoint: "0.0.0.0:14250"当启用thrift_http协议时,Tempo 同样会设置IncludeMetadata = true以支持多租户(见 shim.go)。
Zipkin Receiver
配置示例:
distributor: receivers: zipkin: endpoint: "0.0.0.0:9411"Zipkin Receiver 始终开启IncludeMetadata(见 shim.go)。
Kafka Receiver
Kafka Receiver 从 Kafka 主题中消费 trace 消息。由于 Tempo 默认配置不包含 kafka Receiver,其配置方式与 Collector 中一致(protocols换成brokers、topic等 Kafka 连接参数)。使用时需在配置中显式声明:
distributor: receivers: kafka: brokers: ["kafka:9092"] topic: "otlp_spans"注意:以上 Kafka 字段仅为示意,实际参数以 contrib 库的 kafkareceiver 配置为准;本文仅从源码确认该工厂已在 Tempo 中注册可用。
数据流转全景:从 Receiver 到 Tempo 后端
将本文内容串联起来,Tempo 中一次完整的 trace 数据接入流程如下:
- 客户端(SDK 或 Agent)以 OTLP gRPC/HTTP、Jaeger 或 Zipkin 协议向 distributor 暴露的端口推送数据;
- 对应 Receiver 按协议解析数据并转换为 OTLP 内部格式(
ptrace.Traces); - Receiver 的 consumer 链(含
Middleware包装)将数据交给receiversShim.ConsumeTraces(见 shim.go); - shim 从 context 提取租户 ID,调用
pusher.PushTraces将数据推入 distributor 核心逻辑,完成接收、限制检查与后续分发; - 之后数据经
storage模块的 WAL 与 block 落盘,供 querier 与 query-frontend 检索。
Tempo 将这一整套 Receiver 生命周期(启动、运行、优雅关闭)封装为 dskit 的services.Service(见 shim.go 与services.NewBasicService),与 distributor 模块自身的生命周期管理无缝集成。
相关阅读路径
- 核心概念文档:vendor/go.opentelemetry.io/collector/receiver/README.md、OTLP Receiver 文档
- Tempo Receiver 实现:modules/distributor/receiver/shim.go、modules/distributor/receiver/middleware.go
- 配置结构定义:modules/distributor/config.go
- 完整示例配置:example/docker-compose/single-binary/tempo.yaml、example/docker-compose/distributed/tempo.yaml、example/docker-compose/debug/tempo.yaml、example/docker-compose/multitenant/tempo.yaml
- 集成测试配置:integration/operations/config-receivers.yaml
- 后端
- 可观测性
- 链路追踪
【免费下载链接】tempo
Grafana Tempo is a high volume, minimal dependency distributed tracing backend.
相关推荐
OpenTelemetry Collector Receiver 完全指南:数据入口的配置、命名与 Pipeline 接入原理
OpenTelemetry Collector Receiver 完全指南:数据入口的配置、命名与 Pipeline 接入原理 接收器(Receiver)是数据
可观测性后端运维观测Grafana Tempo 中的 Kafka Receiver:基于 OpenTelemetry Collector Contrib 的 Kafka 遥测消费与管线元数据传递实践指南
Grafana Tempo 中的 Kafka Receiver:基于 OpenTelemetry Collector Contrib 的 Kafka 遥测消费与
后端可观测性链路追踪Grafana Tempo 中的 Jaeger Receiver:多协议追踪数据接入与配置实战
Grafana Tempo 中的 Jaeger Receiver:多协议追踪数据接入与配置实战 Jaeger Receiver 是 OpenTelemetry
后端可观测性链路追踪
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考