自从迁移到 Spring Boot 3.0 以来,跟踪已停止与计划作业一起工作
@Scheduled(fixedDelay = 69, timeUnit = TimeUnit.SECONDS)
根据迁移文档,我们应该使用
ContextScheduledExecutorService.wrap()
https://github.com/micrometer-metrics/tracing/wiki/Spring-Cloud-Sleuth-3.1-Migration-Guide#async-instrumentation 来包装执行器服务
根据 spring 文档,我们应该能够这样做
@Configuration
@EnableScheduling
public class AppConfig implements SchedulingConfigurer {
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
taskRegistrar.setScheduler(taskExecutor());
}
@Bean(destroyMethod="shutdown")
public Executor taskExecutor() {
return ContextScheduledExecutorService.wrap(Executors.newScheduledThreadPool(100));
}
}
正在使用正确的调度程序,因为我在设置调度程序时可以看到自定义线程名称,但日志跟踪未显示(traceId、spanId)。否则,跟踪工作就像我在同一应用程序中调用 api 方法时所看到的那样。
我也遇到了同样的问题,并找到了一些对我有用的解决方案。你可以做这样的事情。
import io.micrometer.tracing.Tracer;
import lombok.RequiredArgsConstructor;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
@Aspect
@Component
@RequiredArgsConstructor
public class ScheduledSpanAspect {
private final Tracer tracer;
@Pointcut("@annotation(org.springframework.scheduling.annotation.Scheduled)")
public void annotatedWithScheduled() {}
@Around("annotatedWithScheduled()")
public Object wrapScheduledIntoSpan(ProceedingJoinPoint pjp) throws Throwable {
var methodName = pjp.getSignature().getDeclaringTypeName() + "." + pjp.getSignature().getName();
var span = tracer.nextSpan()
.name(methodName)
.start();
try (var ignoredSpanInScope = tracer.withSpan(span.start())) {
return pjp.proceed();
} finally {
span.end();
}
}
}
在这里找到它
更新: 这应该可以从 Spring Boot
3.2.0
/ Spring Framework 6.1.0
(2023 年 11 月)获得。
我们计划在未来添加它:https://github.com/spring-projects/spring-framework/issues/29883
同时,作为解决方法,您可以在
@Observed
方法上添加 ObservedAspect
注释(+创建 @Scheduled
bean)或在其中手动创建 Observation
。