2. OpenTelemetry 架构:整体架构、组件及数据流

OpenTelemetry 并非一个单一的二进制或库,而是一套规范、SDK、工具和协议的集合。其核心架构围绕“产生 → 处理 → 导出”这一管道设计,确保从应用代码到后端存储的整个链路具备高度可扩展性与厂商无关性。

2.1 整体架构分层

OpenTelemetry 架构从上到下可分为四个逻辑层:

层级 职责 典型组件
Instrumentation(插桩层) 自动或手动在应用中创建 Span、Metric、Log 记录 SDK、API、自动插桩库(如 Java Agent、Python 装饰器)
Processor(处理器层) 对采集到的数据进行过滤、批处理、采样、属性增强 SpanProcessor、MetricReader、LogRecordProcessor
Exporter(导出器层) 将处理后的数据序列化并发送到后端 OTLP Exporter、Jaeger Exporter、Prometheus Exporter
Collector(收集器层) 作为独立代理或网关,接收、处理、转发遥测数据 OpenTelemetry Collector(otelcol)
架构要点: 插桩层与导出器层之间通过 Processor 解耦,Collector 则作为可选的中转枢纽,极大降低了后端切换的改造成本。

2.2 核心组件详解

2.2.1 Instrumentation(插桩)

插桩是数据产生的起点。OpenTelemetry 提供两种插桩方式:

  • 自动插桩(Auto-Instrumentation):通过字节码增强(Java Agent)、猴子补丁(Python)、中间件钩子(Node.js)等方式,零代码侵入地捕获常见框架(HTTP、gRPC、数据库驱动)的调用链。
  • 手动插桩(Manual Instrumentation):开发者通过 OpenTelemetry API 显式创建 Span、设置属性、记录事件,适用于自定义业务逻辑的深度观测。

2.2.2 Processor(处理器)

Processor 位于 SDK 内部,在数据从 Span/Metric 产生后、交给 Exporter 之前执行。常见处理器类型:

  • BatchSpanProcessor:将多个 Span 合并为一批后再导出,减少网络开销。
  • SimpleSpanProcessor:每个 Span 生成后立即导出,适合调试场景。
  • SamplingProcessor:基于头部采样或尾部采样策略,决定哪些 Span 保留。
  • AttributeProcessor:动态添加、删除或修改 Span 属性(如注入环境标签)。

2.2.3 Exporter(导出器)

Exporter 负责将内存中的遥测数据转换为特定协议并发送。OpenTelemetry 原生支持多种导出目标:

导出器名称 协议/格式 典型后端
OTLP Exporter gRPC / HTTP + Protobuf OpenTelemetry Collector、Jaeger、Zipkin
Jaeger Exporter Thrift over UDP/HTTP Jaeger 后端
Prometheus Exporter HTTP / OpenMetrics Prometheus Server
Console Exporter 标准输出(JSON) 本地调试

2.2.4 Collector(收集器)

OpenTelemetry Collector 是一个独立的二进制进程,作为遥测数据的中转与处理枢纽。它支持三种部署模式:

  • Agent 模式:与应用同机部署,作为 Sidecar 或 DaemonSet 运行,负责本地数据预处理与转发。
  • Gateway 模式:独立集群部署,接收来自多个 Agent 的数据,进行全局采样、脱敏、路由后发送到后端。
  • Standalone 模式:直接接收应用 SDK 的 OTLP 数据,适合中小规模场景。
最佳实践: 生产环境推荐使用 Collector 作为统一网关,利用其内置的 batch、memory_limiter、filter 等处理器,避免后端被突发流量打垮。

2.3 数据流全景

下图展示了从应用插桩到后端存储的完整数据流动路径:

OpenTelemetry 数据流全景图 OpenTelemetry 数据流全景 应用代码 (自动/手动插桩) SDK Processor 批处理 / 采样 / 属性增强 Exporter OTLP / Jaeger / Prometheus OpenTelemetry Collector 接收 → 处理 → 路由 OTLP gRPC/HTTP 后端存储 Jaeger / Prometheus / Loki 直接导出(无 Collector) 数据流说明 1. 应用产生 Span/Metric/Log 2. SDK Processor 预处理 3. Exporter 序列化发送 4. Collector 可选中转与增强

2.4 数据流关键路径

根据是否引入 Collector,数据流存在两种典型路径:

  1. 直连路径(SDK → Backend):适用于开发环境或小规模部署。SDK 中的 Exporter 直接将数据发送到 Jaeger、Prometheus 等后端。优点是架构简单,缺点是后端耦合度高,缺乏集中处理能力。
  2. 代理路径(SDK → Collector → Backend):生产环境推荐方案。SDK 仅通过 OTLP 协议将数据发送到本地 Collector,Collector 负责批处理、过滤、采样、脱敏,再转发到后端。后端切换时只需修改 Collector 配置,应用无需变更。
避坑提示: 直连路径下,如果后端出现故障或网络抖动,SDK 内部的 Exporter 重试机制可能导致应用线程阻塞。务必配置 BatchSpanProcessor 的队列大小与超时参数,或使用 Collector 作为缓冲层。

2.5 组件协作示例(代码片段)

以下是一个典型的 Java SDK 初始化配置,展示 Processor 与 Exporter 的串联关系:

// 配置 BatchSpanProcessor + OTLP Exporter
SpanExporter otlpExporter = OtlpGrpcSpanExporter.builder()
    .setEndpoint("http://localhost:4317")
    .build();

SpanProcessor batchProcessor = BatchSpanProcessor.builder(otlpExporter)
    .setMaxQueueSize(2048)
    .setMaxExportBatchSize(512)
    .setScheduleDelay(5, TimeUnit.SECONDS)
    .build();

// 注册到 OpenTelemetry SDK
OpenTelemetrySdk.builder()
    .setTracerProvider(
        SdkTracerProvider.builder()
            .addSpanProcessor(batchProcessor)
            .build()
    )
    .build();

在 Collector 端,对应的接收器与导出器配置如下:

receivers:
  otlp:
    protocols:
      grpc:
        endpoint: 0.0.0.0:4317

processors:
  batch:
    timeout: 5s
    send_batch_size: 512

exporters:
  jaeger:
    endpoint: jaeger-collector:14250
    tls:
      insecure: true

service:
  pipelines:
    traces:
      receivers: [otlp]
      processors: [batch]
      exporters: [jaeger]
架构总结: OpenTelemetry 通过“插桩 → 处理器 → 导出器 → 收集器”的四层架构,实现了数据产生与数据消费的完全解耦。开发者只需关注插桩层的正确性,运维人员通过 Collector 配置即可灵活控制数据路由与处理策略,这正是 OpenTelemetry 成为可观测性标准的核心优势。