4. OpenTelemetry 核心概念:TracerProvider、Span、SpanContext、Sampler、Exporter、Instrumentation 库
在 BFF 层实施全链路监控,首先需要理解 OpenTelemetry 的六大核心概念。它们构成了数据产生、处理、关联与导出的完整链路。下面逐一拆解其职责与协作关系。
4.1 TracerProvider — 追踪的入口与工厂
TracerProvider 是 OpenTelemetry 追踪系统的核心入口。它负责创建 Tracer 实例,并持有全局配置,包括 Sampler、Exporter 和资源信息(Resource)。在 BFF 层,通常每个服务进程只初始化一个全局 TracerProvider。
| 职责 | 说明 |
|---|---|
| 创建 Tracer | 通过 getTracer(name, version) 返回指定名称的 Tracer 实例 |
| 管理配置 | 统一设置 Sampler、SpanProcessor、Exporter 和 Resource |
| 生命周期 | 应用启动时初始化,关闭时优雅刷新未导出的 Span |
app.ts)中尽早初始化 TracerProvider,并设置 service.name 为 BFF 服务名,便于后续区分不同 BFF 实例的追踪数据。
4.2 Span — 追踪的基本工作单元
Span 代表一个操作的时间片段,例如一次 HTTP 请求、一个数据库查询或一个内部函数调用。每个 Span 记录操作名称、开始/结束时间戳、属性(Attributes)、事件(Events)和状态(Status)。
- Span 层级: 通过父子关系形成追踪树(Trace Tree)。根 Span 代表整个请求,子 Span 代表内部子操作。
- Span 生命周期:
Start→ 添加属性/事件 →End。 - 关键属性:
http.method、http.url、http.status_code、error等。
// Node.js 示例:手动创建 Span
const tracer = trace.getTracer('bff-tracer');
const span = tracer.startSpan('POST /api/order');
span.setAttribute('http.method', 'POST');
span.setAttribute('http.url', '/api/order');
// ... 执行业务逻辑
span.end();
4.3 SpanContext — 跨进程传播的身份证
SpanContext 是 Span 的不可变标识信息,包含 TraceId 和 SpanId,以及可选的 TraceFlags 和 Tracestate。它通过 HTTP 头(如 traceparent)在服务间传播,实现跨 BFF 与上游/下游服务的链路关联。
| 字段 | 长度 | 说明 |
|---|---|---|
| TraceId | 16 字节(128 位) | 全局唯一追踪 ID,标识整条请求链路 |
| SpanId | 8 字节(64 位) | 当前 Span 的唯一标识 |
| TraceFlags | 1 字节 | 追踪选项,如是否采样 |
| Tracestate | 可变 | 厂商自定义的追踪上下文数据 |
4.4 Sampler — 采样决策者
Sampler 决定哪些 Span 被记录并导出。在高并发 BFF 场景下,全量采样会带来巨大的存储和性能开销,因此采样策略至关重要。
- AlwaysOn: 采样所有 Span,适合低流量或调试环境。
- AlwaysOff: 关闭所有采样,适合禁用追踪。
- TraceIdRatioBased: 基于 TraceId 的哈希值按比例采样,例如 10% 采样率。
- ParentBased: 继承父 Span 的采样决策,确保整条链路一致。
// 配置 10% 采样率
const sampler = new TraceIdRatioBasedSampler(0.1);
const provider = new BasicTracerProvider({
sampler: sampler,
});
4.5 Exporter — 数据导出通道
Exporter 负责将 Span 数据发送到后端存储或分析系统(如 Jaeger、Zipkin、Prometheus、OTLP Collector)。BFF 层通常使用 BatchSpanProcessor 配合 Exporter,以批量、异步方式导出,减少对请求路径的性能影响。
| Exporter 类型 | 协议 | 适用后端 |
|---|---|---|
| OTLP Exporter | gRPC / HTTP | OpenTelemetry Collector |
| Jaeger Exporter | Thrift / gRPC | Jaeger |
| Zipkin Exporter | JSON / Thrift | Zipkin |
| Console Exporter | 标准输出 | 调试日志 |
4.6 Instrumentation 库 — 零侵入埋点
Instrumentation 库 为常见框架和库提供自动埋点能力,无需手动修改业务代码。在 BFF 层,最常用的 Instrumentation 库包括:
- @opentelemetry/instrumentation-http: 自动追踪 HTTP 客户端和服务器请求。
- @opentelemetry/instrumentation-express: 自动追踪 Express 路由处理。
- @opentelemetry/instrumentation-grpc: 自动追踪 gRPC 调用。
- @opentelemetry/instrumentation-fetch: 自动追踪浏览器 Fetch API。
// 注册 HTTP 和 Express 自动埋点
const { HttpInstrumentation } = require('@opentelemetry/instrumentation-http');
const { ExpressInstrumentation } = require('@opentelemetry/instrumentation-express');
registerInstrumentations({
instrumentations: [
new HttpInstrumentation(),
new ExpressInstrumentation(),
],
});
4.7 核心概念总结
六大概念在 BFF 全链路监控中各司其职:
| 概念 | 一句话职责 | BFF 关注点 |
|---|---|---|
| TracerProvider | 追踪系统的全局工厂 | 初始化时机、Resource 配置 |
| Span | 记录一个操作的时间片段 | 属性、事件、状态、父子关系 |
| SpanContext | 跨进程传播的追踪标识 | HTTP 头注入与提取 |
| Sampler | 控制采样率,降低存储开销 | 高并发下选择 ParentBased + 比例采样 |
| Exporter | 将 Span 数据发送到后端 | BatchSpanProcessor + OTLP 协议 |
| Instrumentation 库 | 自动埋点,减少手动代码 | 覆盖 HTTP、Express、gRPC 等 |