开启执行超时功能,需要配置:
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 { |