Hystrix 源码解析 —— 断路器 HystrixCircuitBreaker
来源:互联网 发布:主板稳定性测试软件 编辑:程序博客网 时间:2024/06/08 18:44
摘要: 原创出处 http://www.iocoder.cn/Hystrix/circuit-breaker/ 「芋道源码」欢迎转载,保留摘要,谢谢!
本文主要基于 Hystrix 1.5.X 版本
- 1. 概述
- 2. HystrixCircuitBreaker
- 3. HystrixCircuitBreaker.Factory
- 4. HystrixCircuitBreakerImpl
- 4.1 构造方法
- 4.2 #subscribeToStream()
- 4.3 #attemptExecution()
- 4.4 #markSuccess()
- 4.5 #markNonSuccess()
- 4.6 #allowRequest()
- 4.7 #isOpen()
1. 概述
本文主要分享 断路器 HystrixCircuitBreaker。
HystrixCircuitBreaker 有三种状态 :
CLOSED
:关闭OPEN
:打开HALF_OPEN
:半开其中,断路器处于
OPEN
状态时,链路处于非健康状态,命令执行时,直接调用回退逻辑,跳过正常逻辑。HystrixCircuitBreaker 状态变迁如下图 :
红线 :初始时,断路器处于
CLOSED
状态,链路处于健康状态。当满足如下条件,断路器从CLOSED
变成OPEN
状态:
- 周期( 可配,
HystrixCommandProperties.default_metricsRollingStatisticalWindow = 10000 ms
)内,总请求数超过一定量( 可配,HystrixCommandProperties.circuitBreakerRequestVolumeThreshold = 20
) 。- 错误请求占总请求数超过一定比例( 可配,
HystrixCommandProperties.circuitBreakerErrorThresholdPercentage = 50%
) 。绿线 :断路器处于
OPEN
状态,命令执行时,若当前时间超过断路器开启时间一定时间(HystrixCommandProperties.circuitBreakerSleepWindowInMilliseconds = 5000 ms
),断路器变成HALF_OPEN
状态,尝试调用正常逻辑,根据执行是否成功,打开或关闭熔断器【蓝线】。推荐 Spring Cloud 书籍:
- 请支持正版。下载盗版,等于主动编写低级 BUG 。
- 程序猿DD —— 《Spring Cloud微服务实战》
- 周立 —— 《Spring Cloud与Docker微服务架构实战》
- 两书齐买,京东包邮。
2. HystrixCircuitBreaker
com.netflix.hystrix.HystrixCircuitBreaker
,Hystrix 断路器接口。定义接口如下代码 :
#allowRequest()
和#attemptExecution()
方法,方法目的基本类似,差别在于当断路器满足尝试关闭条件时,前者不会将断路器不会修改状态(CLOSE => HALF-OPEN
),而后者会。HystrixCircuitBreaker 有两个子类实现 :
- NoOpCircuitBreaker :空的断路器实现,用于不开启断路器功能的情况。
- HystrixCircuitBreakerImpl :完整的断路器实现。
在 AbstractCommand 创建时,初始化 HystrixCircuitBreaker ,代码如下 :
- 当
HystrixCommandProperties.circuitBreakerEnabled = true
时,即断路器功能开启,使用 Factory 获得 HystrixCircuitBreakerImpl 对象。在 「3. HystrixCircuitBreaker.Factory」 详细解析。- 当
HystrixCommandProperties.circuitBreakerEnabled = false
时,即断路器功能关闭,创建 NoOpCircuitBreaker 对象。另外,NoOpCircuitBreaker 代码简单到脑残,点击 链接 查看实现。3. HystrixCircuitBreaker.Factory
com.netflix.hystrix.HystrixCircuitBreaker.Factory
,HystrixCircuitBreaker 工厂,主要用于:
- 创建 HystrixCircuitBreaker 对象,目前只创建 HystrixCircuitBreakerImpl 。
HystrixCircuitBreaker 容器,基于 HystrixCommandKey 维护了 HystrixCircuitBreaker 单例对象 的映射。代码如下 :
整体代码灰常清晰,点击 链接 查看代码。
4. HystrixCircuitBreakerImpl
com.netflix.hystrix.HystrixCircuitBreaker.HystrixCircuitBreakerImpl
,完整的断路器实现。我们来逐个方法看看 HystrixCircuitBreakerImpl 的具体实现。
4.1 构造方法
构造方法,代码如下 :
- Status 枚举类,断路器的三种状态。
status
属性,断路器的状态。circuitOpened
属性,断路器打开,即状态变成OPEN
的时间。activeSubscription
属性,基于 Hystrix Metrics 对请求量统计 Observable 的订阅,在 「4.2 #subscribeToStream()」 详细解析。4.2 #subscribeToStream()
#subscribeToStream()
方法,向 Hystrix Metrics 对请求量统计 Observable 的发起订阅。代码如下 :
第 5 至 7 行 :向 Hystrix Metrics 对请求量统计 Observable 的发起订阅。这里的 Observable 基于 RxJava Window 操作符。
FROM 《ReactiveX文档中文翻译》「Window」
定期将来自原始 Observable 的数据分解为一个 Observable 窗口,发射这些窗口,而不是每次发射一项数据
- 简单来说,固定间隔,
#onNext()
方法将不断被调用,每次计算断路器的状态。第 22 行 :判断周期( 可配,
HystrixCommandProperties.default_metricsRollingStatisticalWindow = 10000 ms
)内,总请求数超过一定量( 可配,HystrixCommandProperties.circuitBreakerRequestVolumeThreshold = 20
) 。
- 这里要注意下,请求次数统计的是周期内,超过周期的不计算在内。例如说,
00:00
内发起了 N 个请求,00:11
不计算这 N 个请求。第 29 行 :错误请求占总请求数超过一定比例( 可配,
HystrixCommandProperties.circuitBreakerErrorThresholdPercentage = 50%
) 。第 37 至 39 行 :满足断路器打开条件,CAS 修改状态(
CLOSED => OPEN
),并设置打开时间(circuitOpened
) 。【补充】第 5 至 7 行 :�� 怕写在上面,大家有压力。Hystrix Metrics 对请求量统计 Observable 使用了两种 RxJava Window 操作符 :
Observable#window(timespan, unit)
方法,固定周期( 可配,HystrixCommandProperties.metricsHealthSnapshotIntervalInMilliseconds = 500 ms
),发射 Observable 窗口。点击 BucketedCounterStream 构造方法 查看调用处的代码。Observable#window(count, skip)
方法,每发射一次(skip
) Observable 忽略count
( 可配,HystrixCommandProperties.circuitBreakerRequestVolumeThreshold = 20
) 个数据项。为什么?答案在第 22 行的代码,周期内达到一定请求量是断路器打开的一个条件。点击 BucketedRollingCounterStream 构造方法 查看调用处的代码。目前该方法有两处调用 :
- 「4.1 构造方法」,在创建 HystrixCircuitBreakerImpl 时,向 Hystrix Metrics 对请求量统计 Observable 的发起订阅。固定间隔,计算断路器是否要关闭(
CLOSE
)。- 「4.4 #markSuccess()」,清空 Hystrix Metrics 对请求量统计 Observable 的统计信息,取消原有订阅,并发起新的订阅。
4.3 #attemptExecution()
如下是
AbstractCommand#applyHystrixSemantics(_cmd)
方法,对HystrixCircuitBreakerImpl#attemptExecution
方法的调用的代码 :
- 使用
HystrixCircuitBreakerImpl#attemptExecution
方法,判断是否可以执行正常逻辑。
#attemptExecution
方法,代码如下 :
- 第 4 至 6 行 :当
HystrixCommandProperties.circuitBreakerForceOpen = true
( 默认值 :false
) 时,即断路器强制打开,返回false
。当该配置接入配置中心后,可以动态实现打开熔断。为什么会有该配置?当 HystrixCircuitBreaker 创建完成后,无法动态切换 NoOpCircuitBreaker 和 HystrixCircuitBreakerImpl ,通过该配置以实现类似效果。- 第 8 至 10 行 :当
HystrixCommandProperties.circuitBreakerForceClose = true
( 默认值 :false
) 时,即断路器强制关闭,返回true
。当该配置接入配置中心后,可以动态实现关闭熔断。为什么会有该配置?当 HystrixCircuitBreaker 创建完成后,无法动态切换 NoOpCircuitBreaker 和 HystrixCircuitBreakerImpl ,通过该配置以实现类似效果。- 第 12 至 13 行 :断路器打开时间(
circuitOpened
) 为”空”,返回true
。- 第 16 至 28 行 :调用
#isAfterSleepWindow()
方法,判断是否满足尝试调用正常逻辑的间隔时间。当满足,使用 CAS 方式修改断路器状态(OPEN => HALF_OPEN
),从而保证有且仅有一个线程能够尝试调用正常逻辑。
#isAfterSleepWindow()
方法,代码如下 :
- 在当前时间超过断路器打开时间
HystrixCommandProperties.circuitBreakerSleepWindowInMilliseconds
( 默认值,5000 ms
),返回true
。4.4 #markSuccess()
当尝试调用正常逻辑成功时,调用
#markSuccess()
方法,关闭断路器。代码如下 :
- 第 3 行 :使用 CAS 方式,修改断路器状态(
HALF_OPEN => CLOSED
)。- 第 6 行 :清空 Hystrix Metrics 对请求量统计 Observable 的统计信息。
- 第 8 至 14 行 :取消原有订阅,发起新的订阅。
- 第 16 行 :设置断路器打开时间为”空” 。
如下两处调用了
#markNonSuccess()
方法 :
markEmits
markOnCompleted
4.5 #markNonSuccess()
当尝试调用正常逻辑失败时,调用
#markNonSuccess()
方法,重新打开断路器。代码如下 :
- 第 3 行 :使用 CAS 方式,修改断路器状态(
HALF_OPEN => OPEN
)。- 第 5 行 :设置设置断路器打开时间为当前时间。这样,
#attemptExecution()
过一段时间,可以再次尝试执行正常逻辑。如下两处调用了
#markNonSuccess()
方法 :
handleFallback
unsubscribeCommandCleanup
4.6 #allowRequest()
#allowRequest()
和#attemptExecution()
方法,方法目的基本类似,差别在于当断路器满足尝试关闭条件时,前者不会将断路器不会修改状态(CLOSE => HALF-OPEN
),而后者会。点击 链接 查看代码实现。4.7 #isOpen()
#isOpen()
方法,比较简单,点击 链接 查看代码实现。
- Hystrix 源码解析 —— 断路器 HystrixCircuitBreaker
- Spring Cloud——断路器监控Hystrix Dashboard&Turbine
- Spring Cloud构建微服务架构—Hystrix断路器
- 熔断器 Hystrix 源码解析 —— 调试环境搭建
- 熔断器 Hystrix 源码解析 —— 执行命令方式
- 熔断器 Hystrix 源码解析 —— 执行结果缓存
- Hystrix 源码解析 —— 命令合并执行
- Hystrix源码解析 —— 调试环境搭建
- Hystrix 源码解析 —— 执行命令方式
- Hystrix 源码解析 —— 执行结果缓存
- 《spring cloud微服务实战》读书笔记——Spring Cloud Hystrix(三)断路器的原理
- SpringCloud Hystrix 断路器
- 断路器(Hystrix)
- SpringCloud--断路器(Hystrix)
- 4.断路器Hystrix
- SpringCloud:断路器(Hystrix)
- SpringCloud断路器(Hystrix)
- 5.断路器(Hystrix)
- Codeforces Round #450 (Div. 2) E. Maximum Questions dp,重载小于号
- 用户填写提示文本框
- java工程师面试题:如何判断链表有环?
- ffmpeg 详细configure命令
- 14、Android开发基础之通过系统提供的方法获取到保存文件的路径
- Hystrix 源码解析 —— 断路器 HystrixCircuitBreaker
- CentOS7.2下cMark编译安装mysql报错解决方案
- codevs1506传话
- Hadoop KMS 透明加密配置以及测试
- MAC 设置环境变量path的几种方法
- 适配器模式
- oracle 生成默认的子分区
- Windows10安装Linux子系统Ubuntu
- 配置kdevelop+stlink 的STM32开发环境