项目中MDC有个bizid会在日志当中打印,但是当开启异步线程之后,主线程的MDC当中的bizid无法复用,效果如下(下面截图为kibana展示的倒排序的日志):
前面一行还有bizid,到下一行就没有bizid了
此时如何做?只需要两步:
一、写一个decorator类
/**
* 因为MDC当中的bizid在异步线程池无法传递,所以需要这个
*
* @author wei.feng
* @date 2021-7-9
*/
public class AsyncTaskDecorator implements TaskDecorator {
@Override
public Runnable decorate(Runnable runnable) {
Map<String, String> contextMap = MDC.getCopyOfContextMap();
return () -> {
try {
MDC.setContextMap(contextMap);
runnable.run();
} finally {
MDC.clear();
}
};
}
}
二、在线程池定义中增加
executor在初始化之前增加executor.setTaskDecorator(new AsyncTaskDecorator());
即可
@Bean(name = "fileProcCall9001TaskExecutor", destroyMethod = "shutdown")
public AsyncTaskExecutor asyncTaskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(propertiesDIY.getAsynctaskExecutorCorepoolsize());
executor.setMaxPoolSize(propertiesDIY.getAsynctaskExecutorMaxpoolsize());
executor.setQueueCapacity(propertiesDIY.getAsynctaskExecutorQueuecapacity());
executor.setKeepAliveSeconds(propertiesDIY.getAsynctaskExecutorKeepaliveseconds());
executor.setAllowCoreThreadTimeOut(propertiesDIY.isAsynctaskExecutorAllowcorethreadtimeout());
executor.setTaskDecorator(new AsyncTaskDecorator());
executor.initialize();
logger.debug("CorePoolSize=" + executor.getCorePoolSize());
logger.debug("MaxPoolSize=" + executor.getMaxPoolSize());
logger.debug("KeepAliveSeconds=" + executor.getKeepAliveSeconds());
return executor;
}
三、最终效果
和之前同样的位置,bizid一直延续下去,这样的话在日志当中就很容易进行检索了!
欢迎关注我的公众号“神游坐忘峰大话IT”,大家一起交流技术!