前言

我们知道使用Feign的时候可以配置Hystrix的超时熔断机制,配置起来其实很简单,简单理解这个Hystrix超时熔断其实就是我们可以给Feign远程调用设置一个超时时间,远程调用超过这个时间后,就会被Hystrix熔断,然后执行我们定义好的熔断回调方法!当然这个设置Feign超时时间并不是真的设置Feign的远程调用超时时间,而是设置Hystrix熔断时间,这个Hystrix的限制是大于Feign的!

假设我们配置了Feign的超时时间为20秒(这里不管设置的是Feign的ReadTimeout还是Ribbon的ReadTimeout)我们先理解为Feign的超时,关于Feign和Ribbon的ReadTimeout区别后期有空再分享!然后我们Feign配置了开启Hystrix,并且设置Hystrix超时为10秒,那么10秒后就会被Hystrix超时捕获,并且熔断回调我们定义的Fallback方法!

代码环境

Provider
Hystrix超时熔断机制源码分析_监听器

Provider-Feign
Hystrix超时熔断机制源码分析_ide_02
Hystrix超时熔断机制源码分析_监听器_03
Hystrix超时熔断机制源码分析_ide_04

consumer
Hystrix超时熔断机制源码分析_远程调用_05
consumer-config

feign:
  hystrix:
    enabled: true
  client:
    config:
      #将调用的微服务名称改成default就配置成全局的了
      default:
        connectTimeout: 2000
        readTimeout: 20000
        loggerLevel: BASIC
    default-to-properties: true #默认是否properties配置文件配置优先


  
hystrix:
  command:
    default:
      execution:
        timeout:
          enabled: true
        isolation:
          thread:
            timeoutInMilliseconds: 10000

请求情况
Provider服务处理耗时20秒,Feign设置readTimeout为20秒,理论上是可以收到请求的,但是我们配置了Hystrix超时熔断,且熔断时间为10秒。所以Hystrix在请求发出前开始计时,等待10秒,发现还没有收到Provider返回,那么就会熔断进入Fallback方法,如下!
Hystrix超时熔断机制源码分析_监听器_06
最终响应
Hystrix超时熔断机制源码分析_ide_07

源码分析

本文只分析Hystrix超时熔断这部分代码,其他后期有空再分享!

入口代码
Hystrix超时熔断机制源码分析_远程调用_08
在AbstractCommand类中的executeCommandAndObserve方法中,关于这个方法其他部分,本文不分析!核心也就是两块逻辑
executeCommandWithSpecifiedIsolation和.lift(new HystrixObservableTimeoutOperator(_cmd))

executeCommandWithSpecifiedIsolation:这个方法中是使用RxJava实现的,Observable.defer通过.subscribeOn(threadPool.getScheduler(new Func0()这行代码实现异步发送数据!关于这部分看下文
Hystrix线程池创建,调用

.lift是RxJava的一个语法大致意思就是便更执行顺序,先执行.lift(new HystrixObservableTimeoutOperator(_cmd))在执行executeCommandWithSpecifiedIsolation方法!这个自己去找RxJava的语法看看!那么关于超时熔断的核心代码就再new HystrixObservableTimeoutOperator(_cmd)这部分逻辑了,注意这里是先执行new HystrixObservableTimeoutOperator(_cmd))在执行executeCommandWithSpecifiedIsolation哦!

创建超时监听器
Hystrix超时熔断机制源码分析_监听器_09
注意这部分断点的打法!
Hystrix超时熔断机制源码分析_监听器_10
这里Hystrix超时监听器不是和Http请求在同一个线程,也不是和Feign远程调用在一个线程,Hystrix超时监听器是独立的一个线程!(Feign中的线程是在线程池中获取的,Hystrix超时监听器是通过ScheduledExecutor实现的!)

启动超时监听器
Hystrix超时熔断机制源码分析_监听器_11
Hystrix超时熔断机制源码分析_分布式_12
这里基于ScheduledExecutor实现的超时监听器的时间就是我们配置Hystrix的超时时间10秒!也就是10秒后调度到Runnable的run方法,注意这里run方法是个独立的线程,所以run方法中的断点也是需要特殊标记才能卡住!
Hystrix超时熔断机制源码分析_ide_13
这里ScheduledFuture执行run的线程名如下!
Hystrix超时熔断机制源码分析_分布式_14
在此设置!
Hystrix超时熔断机制源码分析_远程调用_15
那么当10秒时间到了后HystrixTimer-xx线程执行到run方法中,然后调用listener.tick();方法!进入超时检查,如果超时了!那么进入熔断逻辑!
Hystrix超时熔断机制源码分析_监听器_16熔断逻辑中的Fallback方法调用都是交给HystrixTimer-xx线程处理的,并不是Http请求线程或者是Feign调度线程!
Hystrix超时熔断机制源码分析_ide_17
那么至此,Hystrix超时熔断机制源码分析就完成了!