在Spring Cloud Sleuth应用程序中,Sleuth跟踪ID是由TraceFilter生成并设置为MDC。但是当多个请求同时执行时,MDC与线程绑定,可能会导致跟踪ID在并发调用中丢失。
为了解决这个问题,可以使用Sleuth的async支持。异步支持会自动将跟踪ID传递给线程池中的所有线程。以下是示例代码:
@Bean public ThreadPoolTaskExecutor asyncExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(10); executor.setMaxPoolSize(50); executor.setQueueCapacity(10); executor.setThreadNamePrefix("Async-"); executor.initialize(); return executor; }
@Autowired private Tracer tracer;
@GetMapping("/async")
public DeferredResult
ListenableFuture future = asyncService.performAsyncTask();
future.addCallback(new ListenableFutureCallback() {
@Override
public void onSuccess(String result) {
tracer.getCurrentSpan().tag("customTag", "value");
result.setResult(result);
}
@Override
public void onFailure(Throwable ex) {
result.setErrorResult(ex);
}
});
return result;
}
在这个示例中,我们使用了Spring的DeferredResult和ListenableFuture接口来执行异步任务。我们还创建了一个名为Async-的线程池,并将其配置为使用10个核心线程,50个最大线程和10个队列容量。我们还注入了当前Tracer实例,并在成功时添加了一个自定义标签。这将确保在跟踪ID丢失时,Sleuth仍然可以跟踪请求。