4. OpenTelemetry 协议与标准:OTel 架构、OTLP 协议、Collector 组件、Instrumentation 库、Exporter 配置
在值班台分布式追踪存储选型之前,必须深入理解 OpenTelemetry(OTel)的协议与标准。OTel 是 CNCF 的第二个毕业级可观测性项目,它统一了数据采集、处理与导出规范,使得追踪、指标、日志三种信号可以基于同一套架构进行标准化处理。本章将拆解 OTel 的核心组件与协议,为后续存储选型奠定数据流基础。
4.1 OTel 整体架构与数据流
OpenTelemetry 采用“采集-处理-导出”三层管道架构。应用通过 Instrumentation 库生成遥测数据,经由 OTLP 协议发送至 Collector,Collector 完成过滤、采样、增强等处理后再通过 Exporter 写入后端存储。下图展示了这一标准数据流:
架构要点:OTel 不绑定任何特定后端。Collector 作为数据枢纽,可以同时向 Jaeger、Tempo、Zipkin 等多个存储导出追踪数据,实现“一次埋点,多处消费”。
4.2 OTLP 协议:数据序列化与传输
OTLP(OpenTelemetry Protocol)是 OTel 的原生数据协议,定义了遥测数据的序列化格式与传输方式。所有 OTel 组件之间默认使用 OTLP 通信。
| 维度 | 说明 | 生产建议 |
|---|---|---|
| 序列化格式 | Protocol Buffers(protobuf) | 二进制紧凑,解析性能高 |
| 传输协议 | gRPC(默认)或 HTTP/1.1 + JSON | 内部网络用 gRPC;公网或受限环境用 HTTP |
| 数据模型 | Resource → Scope → Span/Log/Metric | Resource 标识服务实例,Scope 标识 Instrumentation 库 |
| 信号类型 | Traces、Metrics、Logs 共用同一协议 | 统一管道,降低运维复杂度 |
| 压缩 | gzip(默认)、zstd、snappy | 高吞吐场景启用 gzip 压缩,减少带宽 |
OTLP 端点示例:Collector 默认监听
4317(gRPC)和 4318(HTTP)端口。应用 SDK 配置如下:
# 应用端 OTLP Exporter 配置(环境变量)
OTEL_EXPORTER_OTLP_ENDPOINT=http://collector.example.com:4317
OTEL_EXPORTER_OTLP_PROTOCOL=grpc
OTEL_EXPORTER_OTLP_COMPRESSION=gzip
OTEL_EXPORTER_OTLP_HEADERS="Authorization=Bearer my-"
4.3 Collector 组件:数据管道核心
OTel Collector 是一个与厂商无关的代理/网关,负责接收、处理和导出遥测数据。它由三个核心子组件构成:Receiver、Processor、Exporter。下图展示了 Collector 的内部管道模型:
4.3.1 常用 Processor 功能对比
| Processor | 功能 | 适用场景 |
|---|---|---|
| batch | 合并多个 Span 为一批次发送 | 降低网络开销,提升吞吐 |
| memory_limiter | 限制 Collector 内存使用上限 | 防止 OOM,保障稳定性 |
| attributes | 增删改 Span 属性 | 统一添加环境标签、脱敏 |
| filter | 根据条件丢弃或保留 Span | 过滤健康检查等低价值追踪 |
| tail_sampling | 基于完整 Trace 决策采样 | 保留慢请求、错误 Trace |
生产注意:Processor 的执行顺序影响最终数据质量。建议将
memory_limiter 放在最前面,batch 放在 Exporter 之前。采样类 Processor 应放在属性处理之后,避免丢失关键标签。
4.4 Instrumentation 库:数据生成源头
Instrumentation 库是嵌入应用代码的 SDK,负责自动或手动创建 Span、记录属性与事件。OTel 提供多语言官方 SDK,并支持主流框架的自动埋点。
- 自动 Instrumentation:通过字节码增强或中间件注入,零代码改动即可为 HTTP、gRPC、数据库调用生成追踪。支持 Java、Python、Node.js、Go、.NET 等。
- 手动 Instrumentation:在关键业务逻辑中显式创建 Span,添加自定义属性与事件。适合需要精细控制追踪粒度的场景。
- 库作者 Instrumentation:框架或中间件开发者直接集成 OTel API,用户无需额外配置即可获得追踪。
Java 自动 Instrumentation 示例:
# 启动时附加 Java Agent
java -javaagent:opentelemetry-javaagent.jar \
-Dotel.service.name=order-service \
-Dotel.exporter.otlp.endpoint=http://collector:4317 \
-jar myapp.jar
该 Agent 会自动拦截 Tomcat、Spring Boot、gRPC、JDBC 等调用,生成完整调用链。
4.5 Exporter 配置:数据输出到存储
Exporter 是 Collector 管道的最后一环,负责将处理后的遥测数据写入后端存储。OTel 支持多种 Exporter,配置方式统一在 Collector 的 YAML 文件中定义。
4.5.1 常用追踪 Exporter 对比
| Exporter | 协议 | 目标存储 | 配置复杂度 |
|---|---|---|---|
| otlp | OTLP gRPC/HTTP | 任何支持 OTLP 的后端 | 低 |
| jaeger | Jaeger Thrift / gRPC | Jaeger 后端 | 低 |
| zipkin | Zipkin JSON / Thrift | Zipkin 后端 | 低 |
| logging | 标准输出 | 控制台/日志文件 | 极低(调试用) |
4.5.2 典型 Exporter 配置示例
# Collector 配置:同时导出到 Jaeger 和 OTLP 后端
exporters:
jaeger:
endpoint: jaeger-collector:14250
tls:
insecure: true
otlp:
endpoint: tempo-distributor:4317
tls:
insecure: true
logging:
loglevel: debug
service:
pipelines:
traces:
receivers: [otlp]
processors: [memory_limiter, batch]
exporters: [jaeger, otlp, logging]
多 Exporter 策略:生产环境建议至少配置两个 Exporter:一个写入主存储(如 Tempo),另一个写入调试日志或备用存储。当主存储故障时,Collector 可以自动重试或降级,保障数据不丢失。