2. OpenTelemetry 基础:OTel 架构概览、Signal 与 Collector 组件

在构建多租户可观测体系之前,必须深入理解 OpenTelemetry(OTel)的核心架构。本章将拆解 OTel 的三大支柱:Signal(信号)、架构组件与Collector(收集器),为后续的租户隔离链路追踪打下坚实的理论基础。

2.1 OTel 整体架构概览

OpenTelemetry 采用 “产生 → 处理 → 导出” 的三层管道架构。数据从应用中的 Instrumentation(埋点) 产生,经过 Collector 的接收、处理、聚合,最终导出到后端存储(如 Jaeger、Prometheus、Datadog)。

下图展示了 OTel 的核心组件及其数据流向:

OpenTelemetry 核心架构图 OpenTelemetry 核心架构图 应用 / 服务 (Java / Go / Python / JS) Instrumentation (SDK/API) OTLP Exporter OpenTelemetry Collector Receivers Processors Exporters Pipelines 后端存储 (Jaeger / Prometheus / Datadog) OTLP/gRPC 💡 架构要点 • 数据流:应用埋点 → OTLP Exporter → Collector (Receiver → Processor → Exporter) → 后端存储 • Collector 是核心枢纽,负责数据接收、处理、路由和导出,是实现租户隔离的关键组件
架构要点: OTel 的管道设计使得数据可以在 Collector 层进行统一的过滤、采样、脱敏和路由,这是实现多租户隔离的基础。租户标签(如 tenant.id)可以在 Processor 阶段注入。

2.2 Signal(信号):Trace / Metric / Log

OTel 将可观测数据抽象为三种核心 Signal。理解它们的定义、关系与差异,是正确使用 OTel 的前提。

Signal 定义 核心数据模型 典型用途
Trace(链路) 记录请求在分布式系统中的完整路径,包含 Span 的父子关系。 Span(名称、开始/结束时间、SpanContext、Attributes、Events) 请求延迟分析、错误定位、依赖关系拓扑
Metric(指标) 对系统状态进行数值化聚合测量,如请求数、CPU 使用率。 Instrument(Counter/Histogram/Gauge)、DataPoint、Attributes 系统监控、告警、容量规划、SLO 跟踪
Log(日志) 带时间戳的离散事件记录,通常包含结构化或非结构化文本。 LogRecord(时间戳、Body、Severity、Attributes) 详细错误排查、审计、业务事件记录
Signal 关联: 在 OTel 中,Trace 和 Log 可以通过 trace_id 和 span_id 进行关联。Metric 虽然不直接包含 Trace ID,但可以通过 Attributes(如 service.name、tenant.id)与 Trace 和 Log 进行上下文关联,形成完整的可观测性视图。

2.3 Collector 组件详解

OpenTelemetry Collector 是一个与供应商无关的代理,负责接收、处理和导出遥测数据。它是 OTel 架构中最灵活的组件,也是实现租户隔离策略的核心战场。

Collector 由以下核心组件构成:

  • Receivers(接收器):负责从各种来源接收数据。常见的有 otlp(接收 OTLP 协议数据)、jaeger、prometheus、filelog 等。
  • Processors(处理器):对数据进行处理、过滤、转换、增强。这是实现租户隔离的关键环节,例如:
    • attributes:添加、修改或删除属性(如注入 tenant.id)。
    • filter:根据条件过滤数据(如丢弃非生产租户的调试日志)。
    • batch:批量处理数据以提高吞吐量。
    • memory_limiter:防止内存溢出。
  • Exporters(导出器):将处理后的数据发送到后端存储或分析平台。常见的有 otlp、jaeger、prometheus、datadog、splunk 等。
  • Pipelines(管道):将 Receivers、Processors 和 Exporters 串联起来,形成完整的数据处理流。一个 Collector 可以定义多个 Pipeline,用于处理不同的 Signal 或租户。
  • Extensions(扩展):提供健康检查、性能分析、pprof 等辅助功能。

下图展示了 Collector 内部的数据处理流程:

Collector 内部数据处理流程 Collector 内部数据处理流程 数据源 Receiver Processors attributes / filter batch / memory_limiter Exporter 后端存储 🔧 Collector 配置示例(YAML) receivers: otlp: # 接收 OTLP 数据 processors: attributes/tenant: # 注入租户 ID actions: [{key: tenant.id, value: "default", action: upsert}]
⚠️ 租户隔离关键点: 在 Processor 阶段,可以通过 attributes 处理器为所有 Span 和 Metric 注入租户标签(如 tenant.id)。后续的 filter 处理器可以根据该标签进行数据路由,确保不同租户的数据被导出到不同的后端或索引,实现逻辑隔离。

2.4 三种 Signal 的租户隔离策略对比

在实现租户隔离时,Trace、Metric 和 Log 的处理方式略有不同。下表总结了各自的隔离策略:

Signal 隔离粒度 常用标签 Collector 处理策略
Trace Span 级别 tenant.id, tenant.name 在 Processor 中注入标签,通过 filter 或 routing 导出到不同后端
Metric DataPoint 级别 tenant.id, service.namespace 通过 Attributes 携带租户信息,在 Prometheus 中使用标签进行查询隔离
Log LogRecord 级别 tenant.id, tenant.region 在日志正文或 Attributes 中嵌入租户 ID,通过 filelog receiver 解析并路由
最佳实践: 建议在应用层(SDK 初始化时)就通过 Resource 或 Span 的 Attributes 携带租户信息。Collector 层负责验证、补充和路由,而不是凭空生成租户标签。这样可以保证数据源的准确性。