前言
我们知道使用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
Provider-Feign
consumer
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超时熔断这部分代码,其他后期有空再分享!
入口代码
在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超时监听器不是和Http请求在同一个线程,也不是和Feign远程调用在一个线程,Hystrix超时监听器是独立的一个线程!(Feign中的线程是在线程池中获取的,Hystrix超时监听器是通过ScheduledExecutor实现的!)
启动超时监听器
这里基于ScheduledExecutor实现的超时监听器的时间就是我们配置Hystrix的超时时间10秒!也就是10秒后调度到Runnable的run方法,注意这里run方法是个独立的线程,所以run方法中的断点也是需要特殊标记才能卡住!
这里ScheduledFuture执行run的线程名如下!
在此设置!
那么当10秒时间到了后HystrixTimer-xx线程执行到run方法中,然后调用listener.tick();方法!进入超时检查,如果超时了!那么进入熔断逻辑!
熔断逻辑中的Fallback方法调用都是交给HystrixTimer-xx线程处理的,并不是Http请求线程或者是Feign调度线程!
那么至此,Hystrix超时熔断机制源码分析就完成了!