开启执行超时功能,需要配置:
HystrixCommandProperties.executionTimeoutEnabled:执行命令超时功能开关- 值:Boolean
- 默认值:
true
HystrixCommandProperties.executionTimeoutInMilliseconds:执行命令超时时长- 值:Integer
- 单位:毫秒
- 默认值:1000毫秒
在AbstractCommand.executeCommandAndObserve方法中,如果HystrixCommandProperties属性中开启了执行命令超时开关,则调用lift实现对执行命令超时的监控。代码如下:
1 | if (properties.executionTimeoutEnabled().get()) { |
HystrixObservableTimeoutOperator
HystrixObservableTimeoutOperator为执行命令加入超时功能。代码如下:
1 | private static class HystrixObservableTimeoutOperator<R> implements Operator<R, R> { |
- 创建订阅
s,添加订阅s到child的订阅 - 获得
HystrixRequestContext。因为下面listener的执行不再当前线程,HystrixRequestContext基于ThreadLocal实现 创建执行命令的超时监听器
TimerListener。当超过执行命令的时长TimerListener.getIntervalTimeInMilliseconds时,TimerListener.tick()方法触发调用- 调用
originalCommand.isCommandTimedOut.compareAndSet(TimedOutStatus.NOT_EXECUTED, TimedOutStatus.TIMED_OUT)尝试将命令中的isCommandTimedOut从NOT_EXECUTED设置为TIMED_OUT。如果设置成功说明命令超时了,于是我们执行命令超时的任务。否则说明run()方法已经执行完了,这里就不用执行了 - 发送命令超时事件
调用
s.unsubscribe()方法取消订阅s。注意,不同执行隔离策略此处的表现不同:ExecutionIsolationStrategy.THREAD:该策略下提供取消订阅,并且命令执行超时,强制取消命令的执行。ExecutionIsolationStrategy.SEMAPHORE:该策略下未提供取消订阅时对超时执行命令的取消。所以,在选择执行隔离策略时要注意这块
执行
child.onError(new HystrixTimeoutException())方法,处理HystrixTimeoutException异常。该异常会被handleFallback处理HystrixContextRunnable设置前面获得的HystrixRequestContext到Callable.run()所在线程的HystrixRequestContext并继续执行。
- 调用
添加
TimerListener到定时器,监听命令的超时执行设置
TimerListener到AbstractCommand.timeoutTimer属性。用于执行超时等场景下的TimerListener的清理。以下方法有通过该属性对TimerListener的清理:- AbstractCommand.handleCommandEnd()
- AbstractCommand.cleanUpAfterResponseFromCache()
创建新的
Subscriber(parent)。在传参的child的基础上,增加了对是否执行超时的判断(isNotTimeOut())和TimerListener的清理- 添加订阅
parent到s的订阅 - 返回
parent
TimerListener
com.netflix.hystrix.util.HystrixTimer.TimerListener是Hystrix定时任务监听器接口。
1 | public static interface TimerListener { |
tick()方法:时间达到(超时)执行的逻辑getIntervalTimeInMilliseconds()方法:返回超时时长
HystrixTimer
com.netflix.hystrix.util.HystrixTimer是Hystrix的定时器。
目前有如下场景使用:
- 执行命令超时任务
- 命令批量执行
构造方法如下:
1 | public class HystrixTimer { |
INSTANCE是单例的静态属性executor属性是定时任务执行器(ScheduledExecutor)
addTimerListener(TimerListener)方法提交定时监听器,生成定时任务。代码如下:
1 | public Reference<TimerListener> addTimerListener(final TimerListener listener) { |
- 调用
startThreadIfNeeded()方法保证executor延迟初始化已完成 - 创建定时任务Runnable。在
Runnable.run()方法里,调用TimerListener.tick()方法 - 调用
scheduleAtFixedRate方法生成定时任务。延迟IntervalTimeInMilliseconds时间后执行listener.tick()方法 - 返回
listener+f创建TimerReference返回
TimerReference
com.netflix.hystrix.util.HystrixTimer.TimerReference是Hystrix的定时任务引用。代码如下:
1 | private static class TimerReference extends SoftReference<TimerListener> { |
- 通过
clear()方法,可以取消定时任务的执行
ScheduledExecutor
com.netflix.hystrix.util.HystrixTimer.ScheduledExecutor是Hystrix定时任务执行器。代码如下:
1 | static class ScheduledExecutor { |