4. 固定采样率配置:AlwaysOn、AlwaysOff、Ratio-based Sampler 的配置与适用场景
固定采样率是 OpenTelemetry 采样策略中最基础、最直接的一类。它不依赖请求属性、不分析链路拓扑,仅根据预设的布尔值或概率决定是否保留 Span。在生产环境中,固定采样率通常用于边界控制(全量采集或完全关闭)以及均匀降噪(按比例丢弃)。
本章将深入剖析三种内置 Sampler 的配置方法、行为差异及典型适用场景,并给出可复用的代码示例。
4.1 三种 Sampler 核心对比
| Sampler 名称 | 决策逻辑 | 采样率 | 典型场景 |
|---|---|---|---|
| AlwaysOnSampler | 始终返回 RECORD_AND_SAMPLE |
100% | 调试环境、关键链路全量追踪、短期性能剖析 |
| AlwaysOffSampler | 始终返回 DROP |
0% | 关闭追踪、压测时不产生 Span、临时禁用 |
| TraceIdRatioBasedSampler | 基于 TraceId 哈希与阈值比较 | 0.0 ~ 1.0 可配 | 生产环境均匀降采样、成本控制、长期基线采集 |
关键认知: AlwaysOn 和 AlwaysOff 是确定性采样,不产生额外计算开销;Ratio-based 需要计算 TraceId 哈希,但开销极低(纳秒级),适合高吞吐场景。
4.2 AlwaysOnSampler:全量采集
当需要不丢失任何一条 Span 时使用。典型场景包括:
- 开发/测试环境全链路调试
- 上线前的全量回归验证
- 短时间(如 5 分钟)的深度性能剖析
Java SDK 配置示例:
// 通过代码设置
SdkTracerProvider tracerProvider = SdkTracerProvider.builder()
.setSampler(Sampler.alwaysOn())
.build();
// 或通过环境变量(优先级低于代码设置)
// OTEL_TRACES_SAMPLER=always_on
Python SDK 配置示例:
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.sampling import ALWAYS_ON
provider = TracerProvider(sampler=ALWAYS_ON)
生产警告: AlwaysOn 在高 QPS(如 > 10,000/s)下会瞬间产生海量 Span,导致 Export 压力、存储成本飙升。务必配合限流或仅在低流量时段使用。
4.3 AlwaysOffSampler:完全关闭
当需要彻底关闭追踪时使用。典型场景:
- 压测/基准测试时避免追踪干扰
- 临时禁用追踪以排查 Exporter 问题
- 对非关键服务永久关闭(节省资源)
Java SDK 配置示例:
SdkTracerProvider tracerProvider = SdkTracerProvider.builder()
.setSampler(Sampler.alwaysOff())
.build();
// 环境变量
// OTEL_TRACES_SAMPLER=always_off
Go SDK 配置示例:
import (
"go.opentelemetry.io/otel/sdk/trace"
)
tp := trace.NewTracerProvider(
trace.WithSampler(trace.AlwaysOff()),
)
注意: AlwaysOff 会丢弃所有 Span,包括根 Span。如果只想丢弃部分子 Span,应使用其他 Sampler 或自定义 Sampler。
4.4 TraceIdRatioBasedSampler:按比例均匀采样
这是生产环境最常用的固定采样策略。它根据 TraceId 的哈希值决定是否采样,保证同一个 Trace 的所有 Span 被一致地采样或丢弃。
配置参数:
| 参数 | 类型 | 说明 |
|---|---|---|
ratio |
double (0.0 ~ 1.0) | 采样比例。0.25 表示 25% 的 Trace 被采样 |
seed(部分实现) |
int | 哈希种子,用于多服务间一致性(非标准参数) |
Java SDK 配置示例:
// 采样 10% 的 Trace
SdkTracerProvider tracerProvider = SdkTracerProvider.builder()
.setSampler(Sampler.traceIdRatioBased(0.1))
.build();
// 环境变量
// OTEL_TRACES_SAMPLER=traceidratio
// OTEL_TRACES_SAMPLER_ARG=0.1
Python SDK 配置示例:
from opentelemetry.sdk.trace.sampling import TraceIdRatioBased
provider = TracerProvider(
sampler=TraceIdRatioBased(rate=0.1)
)
4.5 采样决策流程(SVG 图)
下图展示了固定采样率在 OpenTelemetry SDK 中的完整决策路径:
4.6 适用场景速查表
| 场景 | 推荐 Sampler | 理由 |
|---|---|---|
| 本地开发调试 | AlwaysOn | 不丢失任何链路,快速定位问题 |
| CI/CD 集成测试 | AlwaysOn | 确保测试覆盖所有追踪路径 |
| 生产环境长期监控 | TraceIdRatioBased (0.01~0.1) | 控制成本,保留代表性样本 |
| 压测/性能基准 | AlwaysOff | 消除追踪开销,获得真实性能数据 |
| 临时故障排查 | AlwaysOn(短时) | 全量采集后切换回 Ratio 模式 |
| 非核心服务 | AlwaysOff 或极低 Ratio | 节省资源,仅保留关键错误链路 |
4.7 配置注意事项
- 环境变量优先级: 代码中显式设置的 Sampler 优先级高于
OTEL_TRACES_SAMPLER环境变量。 - 多服务一致性: Ratio-based Sampler 依赖 TraceId 哈希,只要所有服务使用相同的 TraceId(通过传播),采样决策就是一致的。
- 动态调整: 固定采样率不支持运行时动态变更。如需动态调整,应使用
Sampler接口的自定义实现或配合配置中心。 - 采样率精度: 对于极低采样率(如 0.001),建议使用 TraceIdRatioBased 而非自定义 Sampler,避免哈希分布不均匀。
最佳实践: 生产环境推荐从 0.1(10%)开始,根据存储预算和查询需求逐步调整。对于高流量服务(QPS > 100,000),0.01(1%)通常已足够。