在工作中同步转异步处理的场景非常多,例如日志记录,图片异步上传等。sleuth中trace链路+ELK收集,可以让我们很直观看到整个完整的链路,我们知道sleuth中在同一线程的链路的传递是通过ThreadLocal来做到的,而http或rpc调用这种方式的链路一般通过添加header头来进行传递的(这个需要我们去自己实现对http请求的拦截处理-当然我们不需要重复造轮子,spring已经帮我们把这些都实现了,我们只需要进行调用正常调用即可),那么如果我们创建一个线程pool,并异步执行数据,那么原线程中的trace信息能否传递到新的线程之中。
我们创建一个线程ThreadPoolTaskExecutor来进行测试(在一个有spring cloud sleuth的环境中测试)。
@Bean
public ThreadPoolExecutor threadPoolExecutor(){
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(10, 10,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
return threadPoolExecutor;
}
@GetMapping(value = "test")
public JsonResult<Boolean> test(){
log.info("进入代码哈哈哈哈哈!!!!");
threadPoolExecutor.execute(()->{
log.info("这是threadPoolExecutor异步执行的哈哈哈哈哈哈");
});
return JsonResult.success();
}
最终的结果我们发现:
trace在两个线程中进行传递了。为何出现这个情况的,我们在被执行的代码中可以debug下发现:
发现在执行的方法栈中多出了TraceRunnable类,但是我们在使用时候并没有创建该类,联想下最终的结果,我们先做出一个猜测,s