hystrix源码小贴士之调用异常处理

Posted zwh1988

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hystrix源码小贴士之调用异常处理相关的知识,希望对你有一定的参考价值。

  executeCommandAndObserve方法处理onerror异常。

return execution.doOnNext(markEmits)
                .doOnCompleted(markOnCompleted)
                .onErrorResumeNext(handleFallback)
                .doOnEach(setRequestContext);

  handleFallback方法处理执行过程中的各种异常

final Func1<Throwable, Observable<R>> handleFallback = new Func1<Throwable, Observable<R>>() {
            @Override
            public Observable<R> call(Throwable t) {
                Exception e = getExceptionFromThrowable(t);
                executionResult = executionResult.setExecutionException(e);
                if (e instanceof RejectedExecutionException) {
                    return handleThreadPoolRejectionViaFallback(e);
                } else if (t instanceof HystrixTimeoutException) {
                    return handleTimeoutViaFallback();
                } else if (t instanceof HystrixBadRequestException) {
                    return handleBadRequestByEmittingError(e);
                } else {
                    /*
                     * Treat HystrixBadRequestException from ExecutionHook like a plain HystrixBadRequestException.
                     */
                    if (e instanceof HystrixBadRequestException) {
                        eventNotifier.markEvent(HystrixEventType.BAD_REQUEST, commandKey);
                        return Observable.error(e);
                    }

                    return handleFailureViaFallback(e);
                }
            }
        };

   handleThreadPoolRejectionViaFallback、handleTimeoutViaFallback、handleBadRequestByEmittingError、handleFailureViaFallback最终都会调用getFallbackOrThrowException来处理各种异常。

  getFallbackOrThrowException方法执行fallback方法并返回结果,如果执行过程中异常,返回异常信息。

private Observable<R> getFallbackOrThrowException(final AbstractCommand<R> _cmd, final HystrixEventType eventType, final FailureType failureType, final String message, final Exception originalException) {
        ...
                Observable<R> fallbackExecutionChain;

                // acquire a permit
                if (fallbackSemaphore.tryAcquire()) {
                    try {
                        if (isFallbackUserDefined()) {
                            executionHook.onFallbackStart(this);
                            fallbackExecutionChain = getFallbackObservable();
                        } else {
                            //same logic as above without the hook invocation
                            fallbackExecutionChain = getFallbackObservable();
                        }
                    } catch (Throwable ex) {
                        //If hook or user-fallback throws, then use that as the result of the fallback lookup
                        fallbackExecutionChain = Observable.error(ex);
                    }

                    return fallbackExecutionChain
                            .doOnEach(setRequestContext)
                            .lift(new FallbackHookApplication(_cmd))
                            .doOnNext(markFallbackEmit)
                            .doOnCompleted(markFallbackCompleted)
                            .onErrorResumeNext(handleFallbackError)
                            .doOnTerminate(singleSemaphoreRelease)
                            .doOnUnsubscribe(singleSemaphoreRelease);
                } else {
                   return handleFallbackRejectionByEmittingError();
                }
            } else {
                return handleFallbackDisabledByEmittingError(originalException, failureType, message);
            }
        }
    }

  handleFallbackError方法,返回一次信息

final Func1<Throwable, Observable<R>> handleFallbackError = new Func1<Throwable, Observable<R>>() {
                    @Override
                    public Observable<R> call(Throwable t) {
                        Exception e = originalException;
                        Exception fe = getExceptionFromThrowable(t);

                        if (fe instanceof UnsupportedOperationException) {
                            long latency = System.currentTimeMillis() - executionResult.getStartTimestamp();
                            logger.debug("No fallback for HystrixCommand. ", fe); // debug only since we‘re throwing the exception and someone higher will do something with it
                            eventNotifier.markEvent(HystrixEventType.FALLBACK_MISSING, commandKey);
                            executionResult = executionResult.addEvent((int) latency, HystrixEventType.FALLBACK_MISSING);

                            /* executionHook for all errors */
                            e = wrapWithOnErrorHook(failureType, e);

                            return Observable.error(new HystrixRuntimeException(failureType, _cmd.getClass(), getLogMessagePrefix() + " " + message + " and no fallback available.", e, fe));
                        } else {
                            long latency = System.currentTimeMillis() - executionResult.getStartTimestamp();
                            logger.debug("HystrixCommand execution " + failureType.name() + " and fallback failed.", fe);
                            eventNotifier.markEvent(HystrixEventType.FALLBACK_FAILURE, commandKey);
                            executionResult = executionResult.addEvent((int) latency, HystrixEventType.FALLBACK_FAILURE);

                            /* executionHook for all errors */
                            e = wrapWithOnErrorHook(failureType, e);

                            return Observable.error(new HystrixRuntimeException(failureType, _cmd.getClass(), getLogMessagePrefix() + " " + message + " and fallback failed.", e, fe));
                        }
                    }
                };

 

以上是关于hystrix源码小贴士之调用异常处理的主要内容,如果未能解决你的问题,请参考以下文章

hystrix源码小贴士之命令四种调用方式的异同

hystrix源码小贴士之之hystrix-metrics-event-stream

hystrix源码小贴士之Yammer Publisher

hystrix源码小贴士之Servo Publisher

hystrix源码小贴士之中断

8.Spring-Cloud-Hystrix之异常处理