springboot~openfeign开启熔断之后MDC为null的理解(feign 熔断配置)

  本篇文章为你整理了springboot~openfeign开启熔断之后MDC为null的理解(feign 熔断配置)的详细内容,包含有spring cloud feign如何开启熔断 feign 熔断配置 feignclient 熔断 spring boot 熔断器 springboot~openfeign开启熔断之后MDC为null的理解,希望能帮助你了解 springboot~openfeign开启熔断之后MDC为null的理解。

  MDC概念

  MDC(Mapped Diagnostic Context,映射调试上下文)是 log4j 和 logback 提供的一种方便在多线程条件下记录日志的功能,也可以说是一种轻量级的日志跟踪工具。

  MDC能做什么

  那么通过MDC的概念,我们可以知道,MDC是应用内的线程级别,不是分布式的应用层级别,所以仅靠它无法做到分布式应用调用链路跟踪的需求。它要解决的问题主要是让我们可以在海量日志数据中快速捞到可用的日志信息。
 

  场景分析。

  既然我们知道MDC底层使用TreadLocal来实现,那根据TreadLocal的特点,它是可以让我们在同一个线程中共享数据的,但是往往我们在业务方法中,会开启多线程来执行程序,这样的话MDC就无法传递到其他子线程了。这时,我们需要使用额外的方法来传递存在TreadLocal里的值。MDC提供了一个叫getCopyOfContextMap的方法,很显然,该方法就是把当前线程TreadLocal绑定的Map获取出来,之后就是把该Map绑定到子线程中的ThreadLocal中了,具体代码如下:

  图中有几个MDCAdapter适配器,我们拿BasicMDCAdapter为例,它的put,get这些方法,实事上是对InheritableThreadLocal Map String, String 类型的变量进行操作的,在主线程中获取值,将值转到子线程里使用它。

  

private InheritableThreadLocal Map String, String inheritableThreadLocal = new InheritableThreadLocal Map String, String () {

 

  public Map String, String getCopyOfContextMap() {

   Map String, String oldMap = inheritableThreadLocal.get();

   if (oldMap != null) {

   return new HashMap String, String (oldMap);

   } else {

   return null;

  public void setContextMap(Map String, String contextMap) {

   inheritableThreadLocal.set(new HashMap String, String (contextMap));

  也就是说,我们在主线程中获取MDC的值,然后在子线程中设置进去,这样,子线程打印的信息也会带有整个调用链共同的traceId了。

  # openfeign

  openfeign开启熔断之后MDC为null,这是有前提的,首先,你的熔断开启后,使用的是线程池的熔断模式,即hystrix.command.default.execution.isolation.strategy=THREAD,或者不写这行,如果值是`SEMAPHORE`模式,是可以获取到MDC对象的,因为这种信号量模式,并没有产生新的线程,所以对于ThreadLocal类型的MDC对象,是可以获取到的。

  # openFeign的熔断配置

  

 

  ribbon:

  ribbon请求连接的超时时间- 限制3秒内必须请求到服务,并不限制服务处理的返回时间

  connectTimeout: 1000

  请求处理的超时时间 下级服务响应最大时间,超出时间消费方(路由也是消费方)返回timeout,超时时间不可大于断路器的超时时间

  readTimeout: 2000
 

  hystrix:
 

  command:
 

  default:
 

  execution:
 

  timeout:
 

  enabled: true
 

  isolation:
 

  strategy: THREAD #信号量模式,无超时时间;THREAD线程池模块,这是默认的
 

  thread:
 

  timeoutInMilliseconds: 3000 #对THREAD模式才有效
 

  feign:
 

  hystrix:
 

  # Feign启用断路器,默认为FALSE,如果开启熔断,如果是线程池模式,会在新线池中发起请求,这时MDC无论获取到,如果是SEMAPHORE模式,是可以获取到MDC的
 

  enabled: true

  

# 在openFeign的拦截器中,获取MDC中的traceId

 

   注意,咱们的这个拦截器获取traceId功能,只是在SEMAPHORE模式才有效【注意,这种模式的熔断是没有超时时间的,所以性能不太好,高并发时,请求慢的慢,容易堆积,造成服务器的雪崩】

  

 

  @Configuration
 

  public class FeignTraceIdInterceptor implements RequestInterceptor {

  

@Override

 

  public void apply(RequestTemplate template) {

   String traceId = MDC.get(TRACE_ID);

   if (traceId != null) {

   template.header(HTTP_HEADER_TRACE, traceId);

  

 

  }

  

在后面的调研中,我们还会针对THREAD模块进行探究,找到获取MDC中traceId的方法,请期待。

 

  以上就是springboot~openfeign开启熔断之后MDC为null的理解(feign 熔断配置)的详细内容,想要了解更多 springboot~openfeign开启熔断之后MDC为null的理解的内容,请持续关注盛行IT软件开发工作室。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: