首页 > 其他分享 >springboot~openfeign开启熔断之后MDC为null的解决

springboot~openfeign开启熔断之后MDC为null的解决

时间:2023-01-30 15:59:13浏览次数:61  
标签:return springboot openfeign MDC 线程 context public Hystrix

上一篇说了关于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这个数据值

标签:return,springboot,openfeign,MDC,线程,context,public,Hystrix
From: https://www.cnblogs.com/lori/p/17076219.html

相关文章

  • SpringBoot单元测试:@SpringBootTest
    接上一篇:SpringBoot整合SSM添加依赖<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId......
  • SpringBoot配置文件详解
    简介SpringBoot全局配置文件默认为src/main/resources下的application.properties,后缀可以改为yml,如果application.yml和application.properties两个配置文件都存在,那么,prop......
  • springboot实现邮件发送功能
    本想使用网易,结果使用465端口尝试了半天,老是提示无法连接,后面说是要开通vip,果断放弃,本次教程使用是qq邮箱,端口号是587,之所以这样是阿里云服务器无法使用25端口发送邮件了......
  • GraalVM和Spring Native尝鲜,一步步让Springboot启动飞起来,66ms完成启动
    简介GraalVM是高性能的JDK,支持Java/Python/JavaScript等语言。它可以让Java变成二进制文件来执行,让程序在任何地方运行更快。这或许是Java与Go的一场战争?下载安装GraalV......
  • springboot~openfeign开启熔断之后MDC为null的理解
    openfeign开启熔断之后MDC为null,这是有前提的,首先,你的熔断开启后,使用的是线程池的熔断模式,即hystrix.command.default.execution.isolation.strategy=THREAD,或者不写这行,如......
  • SpringBoot3.x SpringCloudGateway与SpringDoc OpenApi整合
     网关的配置文件这个是用来转发各个服务的 /v3/api-docs请求routes:#转发swagger接口-id:openapiuri:http://localhost:${......
  • springboot 怎么启动aop @EnableAspectJAutoProxy
    SpringBoot项目使用aophttps://blog.csdn.net/qq_39176307/article/details/124714191Spring-AOPSpringBoot自动配置和启动SpringAOPhttps://www.bbsmax.com/A/QV5ZX3......
  • springboot配置文件读取顺序
    若application.yml和bootStrap.yml在同一目录下,则bootStrap.yml的加载顺序要高于application.yml,即bootStrap.yml会优先被加载。原理:bootstrap.yml用于应用程序上......
  • springboot实现连接多个数据源
    dynamicdatasource导入依赖<dependency><groupId>com.baomidou</groupId><artifactId>dynamic-datasource-spring-boot-starter</artifactId>......
  • SpringBoot中配置Redis
    SpringBoot中整合Redis缓存背景:工作中需要用到缓存之前都是用ConcurrentHashMap公司不让用redis那我就小试牛刀一下前端的App、网页在登录时,或是用户在进行一些敏感......