当命令执行失败时,Hystrix将会执行失败回退逻辑,失败的原因可能是:
construct()
或run
方法抛出异常- 当线路是开路,导致命令被短路时
- 当命令对应的线程池或信号量被占满
- 超时
Hystrix执行命令整体流程如下图:
- 红圈:Hystrix命令执行失败,执行回退逻辑。也就是大家经常在文章中看到的”服务降级”
绿圈:四种情况会触发失败回退逻辑(fallback)
- 第一种:
short-circuit
。处理链路处于熔断的回退逻辑,在handleShortCircuitViaFallback()
详细解析。 - 第二种:
semaphore-rejection
。处理信号量获得失败的回退逻辑,在handleSemaphoreRejectionViaFallback()
详细解析。 - 第三种:
thread-pool-rejection
。处理线程池提交任务拒绝的回退逻辑,在handleThreadPoolRejectionViaFallback()
详细解析。 - 第四种:
execution-timeout
。处理命令执行超时的回退逻辑,在handleTimeoutViaFallback()
详细解析。 - 第五种:
execution-failure
。处理命令执行异常的回退逻辑,在handleFailureViaFallback()
详细解析。 第六种:
bad-request
。HystrixBadRequestException
和hystrix-javanica
子项目相关。另外,
handleXXXX()
方法,整体代码比较类似,最终都是调用getFallbackOrThrowException()
方法,获得”回退逻辑”或者”异常Observable”。在getFallbackOrThrowException
详细解析。
- 第一种:
handleFallback
在AbstractCommand.executeCommandAndObserve()
方法中,首先调用executeCommandWithSpecifiedIsolation
方法获取命令执行Observable
,然后在Observable中加入回调函数:
1 | return execution.doOnNext(markEmits) |
可以看到,通过调用Observable.onErrorResumeNext
方法实现命令执行Observable
执行异常时,返回回退逻辑Observable
,执行失败回退逻辑。
handleFallback
变量的代码如下:
1 | final Func1<Throwable, Observable<R>> handleFallback = new Func1<Throwable, Observable<R>>() { |
- 标记断路器尝试成功
- 标记
executionResult
执行异常 thread-pool-rejection
,处理线程池提交任务拒绝的回退逻辑,在handleThreadPoolRejectionViaFallback
详细解析execution-timeout
,处理命令执行超时的回退逻辑,在handleTimeoutViaFallback
详细解析bad-request
,和hystrix-javanica
子项目相关execution-failure
处理命令执行异常的回退逻辑,在handleFailureViaFallback
详细解析
handleShortCircuitViaFallback
AbstractCommand.applyHystrixSemantics
方法在执行过程中会调用circuitBreaker.attemptExecution()
判断熔断器的状态。如果链路处于熔断状态,则调用handleShortCircuitViaFallback()
方法处理回退逻辑。
1 | private Observable<R> handleShortCircuitViaFallback() { |
- 发送
SHORT_CIRCUITED
Hystrix事件 - 标记executionResult执行异常
- 调用
getFallbackOrThrowException
获得回退逻辑Observable,并返回
handleSemaphoreRejectionViaFallback
AbstractCommand.applyHystrixSemantics
方法在执行过程中会调用executionSemaphore.tryAcquire()
尝试获取信号量。如果信号量获取失败调用handleSemaphoreRejectionViaFallback
处理信号量获取失败的回退逻辑。
1 | private Observable<R> handleSemaphoreRejectionViaFallback() { |
- 标记executionResult执行异常
- 发送
SEMAPHORE_REJECTED
Hystrix事件 - 调用
getFallbackOrThrowException
获得回退逻辑Observable,并返回
handleThreadPoolRejectionViaFallback
handleThreadPoolRejectionViaFallback
方法处理线程池提交任务拒绝的回退逻辑,前文提到在handleFallback
方法中被调用。
1 | private Observable<R> handleThreadPoolRejectionViaFallback(Exception underlying) { |
- 发送
THREAD_POOL_REJECTED
Hystrix事件 - 标记
threadPool
拒绝执行 - 调用
getFallbackOrThrowException
获得回退逻辑Observable,并返回
handleTimeoutViaFallback
handleThreadPoolRejectionViaFallback
方法处理命令执行超时的回退逻辑,前文提到在handleFallback
方法中被调用。
1 | private Observable<R> handleTimeoutViaFallback() { |
- 调用
getFallbackOrThrowException
获得回退逻辑Observable,并返回
handleFailureViaFallback
handleThreadPoolRejectionViaFallback
方法处理命令执行异常的回退逻辑,前文提到在handleFallback
方法中被调用。
1 | private Observable<R> handleFailureViaFallback(Exception underlying) { |
- 发送
FAILURE
Hystrix事件 - 标记executionResult执行异常
- 调用
getFallbackOrThrowException
获得回退逻辑Observable,并返回
getFallbackOrThrowException
getFallbackOrThrowException
获取回退逻辑Observable
或者异常Observabel
。
1 | private Observable<R> getFallbackOrThrowException(final AbstractCommand<R> _cmd, final HystrixEventType eventType, final FailureType failureType, final String message, final Exception originalException) { |
- 记录
HystrixRequestContext
- 标记executionResult添加事件
- 调用
isUnrecoverable(Exception)
方法,若异常不可恢复,直接返回异常Observable
- 调用
isRecoverableError(Exception)
方法,若异常可恢复,打印WARN日志 - 调用
properties.fallbackEnabled().get()
判断失败回退功能是否开启。如果失败回退功能关闭,调用handleFallbackDisabledByEmittingError
返回异常Observable
- 新建
setRequestContext
。设置RequesgtContext
的Action - 新建
markFallbackEmit
。标记回退发射的Action - 新建
markFallbackCompleted
。回退完成的Action 新建
handleFallbackError
。处理回退逻辑执行发射异常的Func1,返回异常Observable
- 调用
getExceptionFromThrowable
方法,获得Exception
。若t
的类型为Throwable时,包装成Exception
。 - 当
fe
的类型为UnsupportedOperationException
时,使用e
+fe
创建HystrixRuntimeException。该异常发生于HystrixCommand.getFallback()
抽象方法未被覆写 - 当
fe
的类型为其他异常时,使用e
+fe
创建HystrixRuntimeException。该异常发生于HystrixCommand.getFallback()
执行发生异常。 - 调用
shouldNotBeWrapped
方法,判断originalException
是ExceptionNotWrappedByHystrix
的实现时,即要求返回的异常Observable
不使用HystrixRuntimeException
包装。 - 返回
异常Observable
,异常为toEmit
- 调用
调用
getFallbackSemaphore
方法,获得失败回退信号量(TryableSemaphore)对象- 创建
singleSemaphoreRelease
,信号量释放Action - 调用
fallbackSemaphore.tryAcquire()
获取信号量。如果失败,调用handleFallbackRejectionByEmittingError
返回异常Observable
- 调用
getFallbackObservable()
方法,创建回退逻辑Observable
:fallbackExecutionChain。 - 为
fallbackExecutionChain
设置各种回调函数,然后返回
回退逻辑
getFallbackObservable
调用AbstractCommand.getFallbackObservable
获得回退逻辑Observable
:
它的实现在HystrixCommand
中:
1 | final protected Observable<R> getFallbackObservable() { |
调用getFallback()
方法获取回退逻辑Observable
,它的实现在GenericCommand
中:
1 | protected Object getFallback() { |
- 调用
getFallbackAction
方法获取回退的CommandAction
,在本示例中获取到的是ConsumerService.fallback()
方法,类型为MethodExecutionAction
- 和正常执行逻辑一样,我们看到最终在
MethodExecutionAction.execute
方法中通过反射调用其中的Method
,返回执行结果。
http://youdang.github.io/2016/02/05/translate-hystrix-wiki-how-it-works/#%E4%BE%9D%E8%B5%96%E9%9A%94%E7%A6%BB
https://github.com/YunaiV/Blog/blob/master/Hystrix/2018_10_31_Hystrix%20%E6%BA%90%E7%A0%81%E8%A7%A3%E6%9E%90%20%E2%80%94%E2%80%94%20%E5%91%BD%E4%BB%A4%E6%89%A7%E8%A1%8C%EF%BC%88%E5%9B%9B%EF%BC%89%E4%B9%8B%E5%A4%B1%E8%B4%A5%E5%9B%9E%E9%80%80%E9%80%BB%E8%BE%91.md