Trace监控与ErrorHandler报警联动的调试实践 - 第3节
3.1 OpenTelemetry 架构总览
OpenTelemetry(OTel)是 CNCF 孵化的可观测性标准,统一了 Trace、Metrics、Logs 三类信号的采集与导出。其核心架构分为四个层次:API、SDK、Exporter 和 Collector。理解这一分层是后续配置与调优的基础。
架构要点: API 定义接口不实现,SDK 提供默认实现与处理管道,Exporter 负责将数据序列化并发送到后端,Collector 作为独立代理或网关进行数据路由与预处理。
3.2 SDK 安装与初始化
SDK 是 OTel 的运行时核心,负责创建 Span、管理上下文、执行采样和导出。以下以 Python 和 Go 为例展示安装与基本初始化。
3.2.1 Python SDK 安装
pip install opentelemetry-api \
opentelemetry-sdk \
opentelemetry-exporter-otlp-proto-grpc \
opentelemetry-instrumentation-flask \
opentelemetry-instrumentation-requests
3.2.2 Go SDK 安装
go get go.opentelemetry.io/otel \
go.opentelemetry.io/otel/sdk \
go.opentelemetry.io/otel/exporters/otlp/otlptrace \
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc
3.2.3 初始化 TracerProvider(Python 示例)
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
# 1. 创建 Exporter
exporter = OTLPSpanExporter(endpoint="http://localhost:4317", insecure=True)
# 2. 创建 SpanProcessor(批量导出)
processor = BatchSpanProcessor(exporter)
# 3. 创建 TracerProvider 并注册 Processor
provider = TracerProvider()
provider.add_span_processor(processor)
# 4. 设置为全局 TraceProvider
trace.set_tracer_provider(provider)
# 5. 获取 Tracer 开始埋点
tracer = trace.get_tracer(__name__)
初始化顺序: Exporter → Processor → Provider → 全局注册。不要跳过
set_tracer_provider,否则自动埋点库无法获取 Provider。
3.3 Exporter 配置详解
Exporter 负责将 Span 数据序列化并发送到后端。OTel 原生支持多种 Exporter,最常用的是 OTLP(OpenTelemetry Protocol)。
| Exporter 类型 | 协议 | 默认端口 | 适用后端 | 推荐场景 |
|---|---|---|---|---|
| OTLP gRPC | gRPC | 4317 | Collector / Jaeger / Tempo | 生产环境,高性能 |
| OTLP HTTP | HTTP/JSON | 4318 | Collector / 云厂商 | 防火墙友好,调试方便 |
| Jaeger | Thrift / gRPC | 6831 / 14250 | Jaeger 后端 | 遗留系统迁移 |
| Zipkin | HTTP/JSON | 9411 | Zipkin 后端 | 与 Zipkin 生态集成 |
| Console | stdout | — | 控制台 | 本地开发调试 |
3.3.1 OTLP Exporter 配置示例(Go)
import (
"go.opentelemetry.io/otel/exporters/otlp/otlptrace"
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc"
)
func newExporter(ctx context.Context) (*otlptrace.Exporter, error) {
// 创建 gRPC 连接选项
opts := []otlptracegrpc.Option{
otlptracegrpc.WithEndpoint("localhost:4317"),
otlptracegrpc.WithInsecure(),
}
// 创建 Exporter
exporter, err := otlptracegrpc.New(ctx, opts...)
if err != nil {
return nil, err
}
return exporter, nil
}
注意: 生产环境务必使用
WithInsecure() 的替代方案——配置 TLS 证书。同时建议设置 WithTimeout() 避免 Exporter 阻塞 SDK 主流程。
3.4 采样策略(Sampling)
采样是控制 Trace 数据量的关键手段。OTel SDK 内置多种采样器,可在不丢失关键链路的前提下大幅降低存储成本。
3.4.1 采样器类型对比
| 采样器 | 策略 | 适用场景 | 注意事项 |
|---|---|---|---|
| AlwaysOn | 100% 采样 | 开发 / 测试环境 | 生产环境慎用,数据量极大 |
| AlwaysOff | 0% 采样 | 禁用 Trace | 仅用于功能开关 |
| TraceIdRatioBased | 基于 TraceID 的固定比例 | 低流量服务,统一比例 | 无法区分高低优先级请求 |
| ParentBased | 继承父 Span 采样决策 | 分布式链路一致性 | 需与上游采样器配合 |
| RateLimiting | 每秒固定 Span 数 | 高流量服务,限流保护 | 可能丢弃突发流量 |
3.4.2 配置 TraceIdRatioBased 采样(Python)
from opentelemetry.sdk.trace.sampling import TraceIdRatioBased
# 10% 采样率
sampler = TraceIdRatioBased(rate=0.1)
provider = TracerProvider(sampler=sampler)
trace.set_tracer_provider(provider)
3.4.3 配置 ParentBased + 比例采样(Go)
import (
"go.opentelemetry.io/otel/sdk/trace"
"go.opentelemetry.io/otel/sdk/trace/sampling"
)
func newProvider() (*trace.TracerProvider, error) {
// 父 Span 决定采样,根 Span 按 20% 采样
sampler := sampling.ParentBased(
sampling.TraceIDRatioBased(0.2),
)
provider := trace.NewTracerProvider(
trace.WithSampler(sampler),
// ... 其他配置
)
return provider, nil
}
采样策略建议: 生产环境推荐 ParentBased(TraceIdRatioBased(0.1~0.5)) 组合。对于核心交易链路,可单独设置 AlwaysOn 采样;对于健康检查等低价值请求,可设置 AlwaysOff 或极低比例。
3.5 本章小结
- OTel 架构:API → SDK → Exporter → Collector,层次清晰,可插拔。
- SDK 安装:Python 和 Go 均提供官方包,注意版本兼容性。
- Exporter 配置:OTLP 是首选协议,支持 gRPC 和 HTTP;生产环境必须配置 TLS 和超时。
- 采样策略:推荐
ParentBased(TraceIdRatioBased)组合,兼顾链路完整性与成本控制。
下节预告: 第 4 章将深入 Trace 上下文传播机制,包括 W3C TraceContext 标准、Baggage 传递以及跨进程/跨服务链路还原。