设为首页 加入收藏

TOP

springboot~openfeign开启熔断之后MDC为null的解决
2023-07-25 21:43:30 】 浏览:37
Tags:springboot openfeign MDC null 解决

上一篇说了关于MDC跨线程为null的理解,而本讲主要说一下,如何去解决它,事实上,Hystrix为我们留了这个口,我们只需要继承HystrixConcurrencyStrategy,然后重写wrapCallable方法,再把这个重写的对象注册到Hystrix里就可以了,跨线程共享数据,可以使用阿里的 transmittable-thread-local组件,如果只是共离MDC的话,可以自己写个组件就行。

一 ThreadMdcUtil用来同步MDC对象

public class ThreadMdcUtil {

	public static <T> Callable<T> wrap(final Callable<T> callable, final Map<String, String> context) {
		return () -> {
			if (context == null) {
				MDC.clear();
			}
			else {
				MDC.setContextMap(context);
			}
			try {
				return callable.call();
			}
			finally {
				MDC.clear();
			}
		};
	}

	public static Runnable wrap(final Runnable runnable, final Map<String, String> context) {
		return () -> {
			if (context == null) {
				MDC.clear();
			}
			else {
				MDC.setContextMap(context);
			}
			try {
				runnable.run();
			}
			finally {
				MDC.clear();
			}
		};
	}

}

重写HystrixConcurrencyStrategy,将主线程的MDC传入Hystrix建立的新线程

/**
 * 线程上下文传递,hystrix的相关实现有兴趣可以看源码, hystrix提供了这个口子可以处理线程间传值问题,这里不做过多赘述
 */
public class RequestContextHystrixConcurrencyStrategy extends HystrixConcurrencyStrategy {

	@Override
	public <T> Callable<T> wrapCallable(final Callable<T> callable) {
		// 使用阿里的 TtlCallable 重新包一层,解决线程间数据传递问题
		// return TtlCallable.get(callable);
		// 使用自定义的包装对象,将当前mdc复制到Hystrix新线程中
		return ThreadMdcUtil.wrap(callable, MDC.getCopyOfContextMap());
	}

}

注册我们的RequestContextHystrixConcurrencyStrategy策略到Hystrix

@Configuration
@Slf4j
public class HystrixCircuitBreakerConfiguration {

	@PostConstruct
	public void init() {
		HystrixPlugins.getInstance().registerConcurrencyStrategy(
				new RequestContextHystrixConcurrencyStrategy());
	}

}

运行结果,使用openFeign时,已经共享了traceId这个数据值

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Zookeeper集群 下一篇day14-JdbcTemplate

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目