spring-cloud-sleuth如何实现按比例采样同时保证错误链路必采集?
需求实现结论
该需求在Spring Cloud Sleuth中可以直接实现,核心是结合头采样+尾采样的组合逻辑,利用Sleuth原生提供的扩展点即可完成配置,无需引入额外第三方组件。
实现逻辑说明
常规的固定采样率属于「头采样」,链路发起时就决定是否采样,性能高但无法预判后续链路是否出错;我们只需要在头采样的基础上叠加「尾采样」判断:链路调用完成后如果携带错误信息,就强制标记整条链路为采样状态,即可同时满足「正常链路按比例采样」、「错误链路全采集」的要求。
具体落地步骤
1. 配置基础正常链路采样率
在配置文件中设置默认的头采样比例,用于正常链路的抽样采集,可根据实际流量大小调整:
spring: sleuth: sampler: probability: 0.1 # 示例为10%的正常链路采样率
2. 自定义Span处理器强制错误链路采样
实现Sleuth提供的SpanHandler接口,在Span生命周期结束时判断是否携带错误,存在错误则强制将所属Trace设置为采样状态,整条链路都会被上报存储:
import brave.handler.MutableSpan; import brave.handler.SpanHandler; import brave.propagation.TraceContext; import org.springframework.stereotype.Component; @Component public class ErrorTraceForceSampler extends SpanHandler { @Override public boolean end(TraceContext context, MutableSpan span, Cause cause) { // 判断当前Span是否标记了异常 if (span.error() != null) { // 强制设置Trace为采样状态,覆盖头采样的不采样决策 context.toBuilder().sampled(true).build(); } return super.end(context, span, cause); } }
3. 可选扩展
如果有慢调用排查需求,还可以在判断逻辑中叠加耗时阈值,超过指定耗时的正常链路也强制采样:
// 示例:链路报错 OR 耗时超过3秒则强制采样,注意duration单位为微秒 if (span.error() != null || span.duration() > 3000000) { context.toBuilder().sampled(true).build(); }
注意事项
- 如果链路日志是直接输出到本地日志文件而非上报到Zipkin等采集端,需要额外调整日志过滤规则,将标记为采样状态的Trace的所有链路日志输出即可
- 高流量场景下如果错误率突增,建议增加错误Trace的熔断上限,比如单分钟错误Trace上报量不超过总流量的20%,避免采集端/存储端被打满
- Spring Cloud Sleuth 3.x及以上版本已经内置了尾采样支持,可直接开启
sleuth.tracer.sampler.tail-based.enabled=true后配置规则,无需自定义SpanHandler
内容的提问来源于stack exchange,提问作者woxihuanxiayua
相关产品推荐
相关产品推荐

