Hystrix 源码解析 —— 命令执行(三)之执行超时
来源:互联网 发布:人工智能眼部疾病治疗 编辑:程序博客网 时间:2024/05/18 00:55
摘要: 原创出处
http://www.iocoder.cn/Hystrix/command-execute-third-timeout/ 「芋道源码」欢迎转载,保留摘要,谢谢!
本文主要基于 Hystrix 1.5.X 版本
- 1. 概述
- 2. HystrixObservableTimeoutOperator
- 3. HystrixTimer
- 3.1 ScheduledExecutor
- 3.2 TimerListener
- 3.3 TimerReference
1. 概述
本文主要分享 Hystrix 命令执行(三)之执行超时。
建议 :对 RxJava 已经有一定的了解的基础上阅读本文。
开启执行超时功能,需要配置 :
HystrixCommandProperties.executionTimeoutEnabled
:执行命令超时功能开关。- 值 :Boolean
- 默认值 :
true
HystrixCommandProperties.executionTimeoutInMilliseconds
:执行命令超时时长。- 值 :Integer
- 单位 :毫秒
- 默认值 :1000 毫秒
在 《Hystrix 源码解析 —— 命令执行(一)之正常执行逻辑》「4. #executeCommandAndObserve(…)」 中,
#executeCommandAndObserve(...)
方法的第 75 行lift(new HystrixObservableTimeoutOperator<R>(_cmd))
,实现了对执行命令超时的监控。- 对
Observable#lift(Operator)
方法不熟悉的同学,在 《RxJava 源码解析 —— Observable#lift(Operator)》 有详细解析。
推荐 Spring Cloud 书籍:
- 请支持正版。下载盗版,等于主动编写低级 BUG 。
- 程序猿DD —— 《Spring Cloud微服务实战》
- 周立 —— 《Spring Cloud与Docker微服务架构实战》
- 两书齐买,京东包邮。
2. HystrixObservableTimeoutOperator
HystrixObservableTimeoutOperator 类,代码如下 :
- 第 12 行 :创建订阅
s
。 - 第 15 行 :添加订阅
s
到child
的订阅。 - 第 18 行 :获得 HystrixRequestContext 。因为下面
listener
的执行不在当前线程,HystrixRequestContext 基于 ThreadLocal 实现。 - 第 20 至 50 行 :创建执行命令超时监听器
listener
( TimerListener ) 。当超过执行命令的时长(TimerListener#getIntervalTimeInMilliseconds()
)时,TimerListener#tick()
方法触发调用。- 第 26 行 :通过
AbstractCommand.isCommandTimedOut
变量 CAS 操作,保证和下面第 60 行的parent
有且只有一方操作成功。TimedOutStatus 状态变迁如下图 : - 第 28 行 :TODO 【2011】【Hystrix 事件机制】
- 第 31 行 :取消订阅
s
。注意 :不同执行隔离策略此处的表现不同。ExecutionIsolationStrategy.THREAD
:该策略下提供取消订阅(#unsubscribe()
),并且命令执行超时,强制取消命令的执行。在 《Hystrix 源码解析 —— 命令执行(二)之执行隔离策略》「6.5 FutureCompleterWithConfigurableInterrupt」 有详细解析。ExecutionIsolationStrategy.SEMAPHORE
:该策略下未提供取消订阅(#unsubscribe()
)时,对超时执行命令的取消。所以,在选择执行隔离策略,要注意这块。
- 第 34 至 41 行 :执行
child#onError(e) 【Subscriber#onError(Throwable)】
方法,处理 HystrixTimeoutException 异常。该异常会被handleFallback
处理,点击 链接 查看,在 《Hystrix 源码解析 —— 请求执行(四)之失败回退逻辑》 详细解析。- HystrixContextRunnable ,设置第 18 行获得的 HystrixRequestContext 到
Callable#run()
所在线程的 HystrixRequestContext ,并继续执行。点击 链接 查看。另外,HystrixContextRunnable 只有此处使用,独立成类的原因是测试用例使用到。
- HystrixContextRunnable ,设置第 18 行获得的 HystrixRequestContext 到
- 第 26 行 :通过
- 第 52 行 :使用 TimerListener 到定时器,监听命令的超时执行。
第 55 行 :设置 TimerListener 到
AbstractCommand.timeoutTimer
属性。用于执行超时等等场景下的 TimerListener 的清理(tl#clear()
)。如下方法有通过该属性对 TimerListener 的清理 :AbstractCommand#handleCommandEnd()
AbstractCommand#cleanUpAfterResponseFromCache()
第 60 至 107 行 :创建新的 Subscriber (
parent
)。在传参的child
的基础上,增加了对是否执行超时的判断(#isNotTimedOut()
)和TimerListener的清理。- 第 111 行 :添加添加订阅
parent
到s
的订阅。整体订阅关系如下 :- 这里看起来
s
有些“多余” ?因为parent
和listener
存在互相引用的情况,通过s
解决。
- 这里看起来
- 第 113 行 :返回
parent
。注意。如果不能理解,建议阅读下 《RxJava 源码解析 —— Observable#lift(Operator)》 。
3. HystrixTimer
com.netflix.hystrix.util.HystrixTimer
,Hystrix 定时器。目前有如下场景使用 :
- 执行命令超时任务,本文详细解析。
- 命令批量执行,在 《Hystrix 源码解析 —— 命令合并执行》「5. CollapsedTask」 详细解析。
HystrixTimer 构造方法,代码如下 :
INSTANCE
静态属性,单例。executor
属性,定时任务执行器( ScheduledExecutor )。
调用
HystrixTimer#addTimerListener(TimerListener)
方法,提交定时监听器,生成定时任务,代码如下 :- 第 2 行 :调用
#startThreadIfNeeded()
方法,保证executor
延迟初始化已完成。#startThreadIfNeeded()
方法 ,比较简单,点击 链接 查看。- ScheduledExecutor 在 「3.1 ScheduledExecutor」 详细解析。
- 第 5 至 15 行 :创建定时任务 Runnable 。在
Runnable#run()
方法里,调用TimerListener#tick()
方法。在 「3.2 TimerListener」 详细解析。 - 第 17 行 :提交定时监听器,生成定时任务
f
( ScheduledFuture )。 - 第 18 行 :使用
listener
+f
创建 TimerReference 返回。在 「3.3 TimerReference」 详细解析。
3.1 ScheduledExecutor
com.netflix.hystrix.util.HystrixTimer.ScheduledExecutor
,Hystrix 定时任务执行器。代码如下 :- 线程池大小(
coreSize
),通过HystrixTimerThreadPoolProperties.corePoolSize
配置。
3.2 TimerListener
com.netflix.hystrix.util.HystrixTimer.TimerListener
,Hystrix 定时任务监听器接口。代码如下 :#tick()
方法 :时间到达( 超时 )执行的逻辑。#getIntervalTimeInMilliseconds()
方法 :返回到达( 超时 )时间时长。
3.3 TimerReference
com.netflix.hystrix.util.HystrixTimer.TimerReference
,Hystrix 定时任务引用。代码如下 :- 通过
#clear()
方法,可以取消定时任务的执行。
- Hystrix 源码解析 —— 命令执行(三)之执行超时
- 熔断器 Hystrix 源码解析 —— 命令执行(三)之执行超时
- 熔断器 Hystrix 源码解析 —— 命令执行(一)之正常执行逻辑
- 熔断器 Hystrix 源码解析 —— 命令执行(二)之执行隔离策略
- Hystrix 源码解析 —— 命令执行(一)之正常执行逻辑
- Hystrix 源码解析 —— 命令执行(二)之执行隔离策略
- 熔断器 Hystrix 源码解析 —— 执行命令方式
- Hystrix 源码解析 —— 命令合并执行
- Hystrix 源码解析 —— 执行命令方式
- Hystrix 源码解析 —— 请求执行(四)之失败回退逻辑
- 熔断器 Hystrix 源码解析 —— 请求执行(四)之失败回退逻辑
- 熔断器 Hystrix 源码解析 —— 执行结果缓存
- Hystrix 源码解析 —— 执行结果缓存
- UiAutomator系列——Appium Android Bootstrap源码分析之命令解析执行(008)
- Appium Android Bootstrap源码分析之命令解析执行
- Appium Android Bootstrap源码分析之命令解析执行
- springMVC源码解析--ViewResolver视图解析器执行(三)
- Hystrix 源码解析 —— 断路器 HystrixCircuitBreaker
- not found for dependency: expected at least 1 bean which qualifies as autowire
- 自定义控件
- 具体智慧编程第二章的loadmovieLens函数
- [LeetCode] 191. Number of 1 Bits
- 进程调度API之preempt_schedule
- Hystrix 源码解析 —— 命令执行(三)之执行超时
- 十二月知识总结
- C语言基础练习(四)
- Effective Java之多个构造参数考虑用构建器(二)
- Swift笔记
- linux字符驱动之异步通知按键驱动
- Wing IDE 6.x 算号器注册机代码
- 企业服务器搭建项目管理软件(禅道)
- java基础学习日志01