Hystrix源码解析--HystrixCircuitBreaker--从实现探讨原理(三)

一、HystrixCircuitBreaker接口的实现者是谁?

HystrixCircuitBreaker接口有两个实现者,分别是:HystrixCircuitBreakerImpl和NoOpCircuitBreaker。NoOpCircuitBreaker是空的断路器实现,用于不开启断路器功能的情况。HystrixCircuitBreakerImpl是完整的断路器的实现。我们重点分析后者。

二、HystrixCircuitBreakerImpl实现思路

首先我们需要搞清楚的一个问题就是,断路器断的是什么?断路器断的其实就是我们对依赖服务的调用,而我们对依赖服务的调用其实被包装在HystrixCommand里面,所以说到底,断路器断的就是HystrixCommand是否需要对依赖服务发起请求,更直白的一点说,就是断HystrixCommand。而我们知道,我们的程序是通过线程去执行的,HystrixCircuitBreakerImpl只是决定要不要去执行的问题。所以作为HystrixCircuitBreakerImpl, 它需要知道HystrixCommand的状态。

在这里,我们需要引入四个概念:HystrixCommandProperties 和 HystrixCommandMetrics。

前文提到过,HystrixCommand包装了我们对依赖服务的请求,例如对这个HystrixCommand的配置与监控统计,就是由上述的两个对象所完成。说到这里,头脑子一定要清醒,我以一张图来说明他们的关系:

三、HystrixCircuitBreakerImpl源码

1、持有的属性


status 属性,断路器的状态。
circuitOpened 属性,记录上一次断路器被打开的时间戳,如果上一次断路器是关闭状态,那么该值就是 -1。
activeSubscription 属性,基于 Hystrix Metrics 对请求量统计 Observable 的订阅,后续详细分析。

2、构造方法

直到这里,我们就知道,要创建一个HystrixCircuitBreakerImpl实例,必须要知道上述提到的四个概念。因为断路器主要是围绕HystrixCommand而生。

3、attemptExecution

解释:

HystrixCommandProperties.circuitBreakerForceOpen = true ( 默认值 :false) 时,即断路器强制打开,返回 false 。当该配置接入配置中心后,可以动态实现打开熔断。为什么会有该配置?当 HystrixCircuitBreaker 创建完成后,无法动态切换 NoOpCircuitBreaker 和 HystrixCircuitBreakerImpl ,通过该配置以实现类似效果。
当 HystrixCommandProperties.circuitBreakerForceClose = true ( 默认值 :false) 时,即断路器强制关闭,返回 true 。当该配置接入配置中心后,可以动态实现关闭熔断。为什么会有该配置?当 HystrixCircuitBreaker 创建完成后,无法动态切换 NoOpCircuitBreaker 和 HystrixCircuitBreakerImpl ,通过该配置以实现类似效果。
断路器上一次被打开得时间戳( circuitOpened ) 为-1,说明断路器是没有打开的,返回 true 。
如果断路器上一次被打开了,那么调用 #isAfterSleepWindow() 方法,判断是否满足尝试调用正常逻辑的间隔时间。当满足,使用 CAS 方式修改断路器状态( OPEN => HALF_OPEN ),从而保证有且仅有一个线程能够尝试调用正常逻辑。

4、markSuccess

当尝试调用attemptExecution正常逻辑成功时,调用 #markSuccess() 方法,关闭断路器。

5、markNonSuccess

猜你喜欢

转载自blog.csdn.net/pfnie/article/details/82317184