Spring Sleuth运行时采样与追踪动态决策配置咨询
嘿,针对你在生产环境里想动态控制Spring Sleuth @NewSpan追踪开关的需求,结合你使用的Spring Boot 1.5.10.RELEASE、Sleuth 1.3.2.RELEASE以及Cloud Edgware.SR2版本,我整理了几个实用的方案,你可以根据实际场景选择:
方案一:利用Sleuth内置配置实现全局/采样率动态控制
Sleuth本身提供了基础的全局开关和采样率配置,你可以直接通过配置文件控制,甚至结合Spring Cloud Config实现运行时动态刷新:
- 在
application.properties或application.yml中添加配置:
如果需要运行时修改配置,结合Spring Cloud Config和Actuator的# 全局追踪开关,设为false时所有Span都不会生成 spring.sleuth.enabled=true # 采样率,范围0-1,0代表完全不采样,1代表全量采样 spring.sleuth.sampler.percentage=1.0/refresh端点,发送POST请求就能动态更新这些值。不过这个方案是全局生效的,会影响包括HTTP自动Span在内的所有追踪逻辑。
方案二:自定义Sampler精准控制
@NewSpan的采样 如果只想针对@NewSpan注解生成的Span做动态开关,可以自定义Sampler,通过业务规则判断是否采样:
- 创建自定义Sampler类:
import org.springframework.cloud.sleuth.Sampler; import org.springframework.cloud.sleuth.Span; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @Component public class DynamicNewSpanSampler implements Sampler { @Value("${sleuth.newspan.enabled:true}") private boolean newSpanEnabled; @Override public boolean isSampled(Span span) { // 通过Span的名称或标签识别是否是@NewSpan生成的Span boolean isTargetNewSpan = span.getName().startsWith("custom-"); // 替换为你的@NewSpan命名规则 if (isTargetNewSpan) { return newSpanEnabled; } // 其他类型的Span保持默认采样逻辑 return true; } // 提供外部修改开关的方法,配合Actuator使用 public void setNewSpanEnabled(boolean newSpanEnabled) { this.newSpanEnabled = newSpanEnabled; } } - 配置让Sleuth使用这个自定义Sampler:
import org.springframework.cloud.sleuth.Sampler; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class SleuthConfig { @Bean public Sampler sampler() { return new DynamicNewSpanSampler(); } } - 搭配Actuator端点实现运行时切换:
可以自定义一个Actuator端点,通过HTTP请求直接修改开关状态,无需重启应用。
方案三:用AOP环绕
@NewSpan注解实现细粒度控制 这种方式通过AOP拦截所有标注@NewSpan的方法,直接决定是否执行追踪逻辑,灵活性最高:
- 先添加AOP依赖(如果项目里还没有):
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> - 创建AOP切面类:
这个方案只会影响import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.springframework.beans.factory.annotation.Value; import org.springframework.cloud.sleuth.Span; import org.springframework.cloud.sleuth.Tracer; import org.springframework.stereotype.Component; @Aspect @Component public class NewSpanDynamicToggleAspect { @Value("${sleuth.newspan.enabled:true}") private boolean newSpanEnabled; private final Tracer tracer; public NewSpanDynamicToggleAspect(Tracer tracer) { this.tracer = tracer; } @Around("@annotation(org.springframework.cloud.sleuth.annotation.NewSpan)") public Object aroundNewSpanMethod(ProceedingJoinPoint joinPoint) throws Throwable { if (!newSpanEnabled) { // 关闭追踪时,直接执行目标方法 return joinPoint.proceed(); } // 开启追踪时,手动模拟@NewSpan的逻辑创建Span Span span = tracer.createSpan(getSpanName(joinPoint)); try { return joinPoint.proceed(); } finally { tracer.close(span); } } private String getSpanName(ProceedingJoinPoint joinPoint) { // 可以从@NewSpan注解中获取指定名称,默认用方法名 return joinPoint.getSignature().getName(); } }@NewSpan标注的方法,不会干扰Sleuth自动生成的其他Span,同时也能通过配置文件动态刷新开关状态。
额外注意事项
- 版本兼容性:你使用的Sleuth 1.3.2和Edgware版本完全匹配,上述所有方案都能正常运行。
- 性能优化:自定义Sampler的性能开销最小,因为是在Span创建前的采样阶段做判断;AOP方案的性能影响也极低,几乎可以忽略。
- 运行时刷新:如果需要生产环境不重启修改开关,记得配置Spring Cloud Config和Actuator的
/refresh端点,确保配置能动态生效。
内容的提问来源于stack exchange,提问作者Art
相关产品推荐
相关产品推荐

