多线程如何使用MDC传递上下文信息

关于利用MDC来实现上下文请求链路追踪,具体可以看我之前写的博客上下文追踪
由于MDC内部使用的是ThreadLocal来在线程中传递上下文信息的,但是我们往往会在代码中使用异步操作,这个时候,父线程的ThreadLocal信息是无法传递给子线程的(阿里开源的inheritableThreadLocal)。这个时候需要用到线程池的装饰器来解决这个问题。
RpcContext和httpHeader都可以用这个装饰器解决多线程传递问题。

public class MdcTaskDecorator implements TaskDecorator {
    @Override
    public Runnable decorate(Runnable runnable) {
        Map<String, String> contextMap = MDC.getCopyOfContextMap();
        RequestAttributes context = RequestContextHolder.currentRequestAttributes();
        return () -> {
            try {
                // Right now: @Async thread context !
                // (Restore the Web thread context's MDC data)
                if (contextMap != null) {
                    MDC.setContextMap(contextMap);
                }
                if (context != null){
                    RequestContextHolder.setRequestAttributes(context);
                }
                runnable.run();
            } finally {
                MDC.clear();
            }
        };
    }
}

然后在你的异步线程池配置文件中加上装饰器。我用的是Spring集合的@Async来实现异步的,加装饰器的代码如下:

@Configuration
public class AsyncConfig extends AsyncConfigurerSupport {

    @Bean("asyncExecutor")
    public ThreadPoolTaskExecutor asyncExecutor() {
        ThreadPoolTaskExecutor threadPool = new ThreadPoolTaskExecutor();
        threadPool.setCorePoolSize(30);
        threadPool.setMaxPoolSize(500);
        threadPool.setWaitForTasksToCompleteOnShutdown(true);
        threadPool.setAwaitTerminationSeconds(60 * 15);
        threadPool.setThreadFactory(
            new ThreadFactoryBuilder().setNameFormat("async-thread-pool-%d").build());
            //指定装饰器
        threadPool.setTaskDecorator(new MdcTaskDecorator());
        return threadPool;
    }

    @Override
    public Executor getAsyncExecutor() {
        return asyncExecutor();
    }
}
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值