51. 采样
可以采用采样来减少从 process 收集和报告的数据。当没有采样 span 时,它不会增加任何开销(noop)。
采样是一个 up-front 决策,这意味着报告数据的决定是在跟踪中的第一个操作中做出的,并且该决策在下游传播。
默认情况下,global 采样器将单个速率应用于所有跟踪的操作。 Tracer.Builder.sampler
控制此设置,默认为跟踪每个请求。
51.1 声明性抽样
一些 applications 需要基于 java 方法的类型或注释 sample。
大多数用户使用 framework 拦截器来自动化这种 policy。以下 example 显示了内部可能如何工作:
@Autowired Tracer tracer;
// derives a sample rate from an annotation on a java method
DeclarativeSampler<Traced> sampler = DeclarativeSampler.create(Traced::sampleRate);
@Around("@annotation(traced)")
public Object traceThing(ProceedingJoinPoint pjp, Traced traced) throws Throwable {
// When there is no trace in progress, this decides using an annotation
Sampler decideUsingAnnotation = declarativeSampler.toSampler(traced);
Tracer tracer = tracer.withSampler(decideUsingAnnotation);
// This code looks the same as if there was no declarative override
ScopedSpan span = tracer.startScopedSpan(spanName(pjp));
try {
return pjp.proceed();
} catch (RuntimeException | Error e) {
span.error(e);
throw e;
} finally {
span.finish();
}
}
51.2 自定义采样
根据操作的不同,您可能希望应用不同的 policies。例如,您可能不希望跟踪对静态资源(如图像)的请求,或者您可能希望跟踪对新 api 的所有请求。
大多数用户使用 framework 拦截器来自动化这种 policy。以下 example 显示了内部可能如何工作:
@Autowired Tracer tracer;
@Autowired Sampler fallback;
Span nextSpan(final Request input) {
Sampler requestBased = Sampler() {
@Override public boolean isSampled(long traceId) {
if (input.url().startsWith("/experimental")) {
return true;
} else if (input.url().startsWith("/static")) {
return false;
}
return fallback.isSampled(traceId);
}
};
return tracer.withSampler(requestBased).nextSpan();
}
51.3 采样 Spring Cloud Sleuth
默认情况下 Spring Cloud Sleuth sets all spans to non-exportable。这意味着跟踪出现在日志中,但不出现在任何 remote store 中。对于测试,默认值通常就足够了,如果仅使用日志(对于 example,使用 ELK 聚合器),则可能只需要它。如果 export span 数据到 Zipkin,还有Sampler.ALWAYS_SAMPLE
设置导出所有内容和ProbabilityBasedSampler
设置 samples 固定部分的 spans。
如果使用
spring-cloud-sleuth-zipkin
,则ProbabilityBasedSampler
是默认值。您可以通过设置spring.sleuth.sampler.probability
来配置导出。传递的 value 需要是从0.0
到1.0
的 double。
可以通过 creating bean 定义来安装采样器,如下面的示例所示:
@Bean
public Sampler defaultSampler() {
return Sampler.ALWAYS_SAMPLE;
}
您可以将 HTTP 标头
X-B3-Flags
设置为1
,或者在进行消息传递时,可以将spanFlags
标头设置为1
。这样做会强制当前 span 可以导出,而不管采样决定如何。