Hystrix源码分析

使用

compile 'org.springframework.cloud:spring-cloud-starter-netflix-hystrix'

注册

Spring Boot-SPI机制

 

 

 

HystrixCircuitBreakerConfiguration.class

HystrixCircuitBreakerConfiguration.class
@Configuration(proxyBeanMethods = false)
public class HystrixCircuitBreakerConfiguration {

    // 注册切面
    @Bean
    public HystrixCommandAspect hystrixCommandAspect() {
        return new HystrixCommandAspect();
    }

    @Bean
    public HystrixShutdownHook hystrixShutdownHook() {
        return new HystrixShutdownHook();
    }

    @Bean
    public HasFeatures hystrixFeature() {
        return HasFeatures
                .namedFeatures(new NamedFeature("Hystrix", HystrixCommandAspect.class));
    }

    /**
     * 当 ApplicationContext 关闭时,确保清除 Hystrix内部状态。
     */
    private class HystrixShutdownHook implements DisposableBean {

        @Override
        public void destroy() throws Exception {
            // Just call Hystrix to reset thread pool etc.
            Hystrix.reset();
        }
    }
}

HystrixCommandAspect.class

@Aspect
public class HystrixCommandAspect {

    private static final Map<HystrixPointcutType, MetaHolderFactory> META_HOLDER_FACTORY_MAP;

    static {
        META_HOLDER_FACTORY_MAP = ImmutableMap.<HystrixPointcutType, MetaHolderFactory>builder()
                .put(HystrixPointcutType.COMMAND, new CommandMetaHolderFactory())
                .put(HystrixPointcutType.COLLAPSER, new CollapserMetaHolderFactory())
                .build();
    }

    @Pointcut("@annotation(com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand)")

    public void hystrixCommandAnnotationPointcut() {
    }

    @Pointcut("@annotation(com.netflix.hystrix.contrib.javanica.annotation.HystrixCollapser)")
    public void hystrixCollapserAnnotationPointcut() {
    }

    @Around("hystrixCommandAnnotationPointcut() || hystrixCollapserAnnotationPointcut()")
    public Object methodsAnnotatedWithHystrixCommand(final ProceedingJoinPoint joinPoint) throws Throwable {
        // 获取方法
        Method method = getMethodFromTarget(joinPoint);
        Validate.notNull(method, "failed to get method from joinPoint: %s", joinPoint);
        // 同时有 @HystrixCommand 和@HystrixCollapser 注解,抛出异常
        if (method.isAnnotationPresent(HystrixCommand.class) && method.isAnnotationPresent(HystrixCollapser.class)) {
            throw new IllegalStateException("method cannot be annotated with HystrixCommand and HystrixCollapser " +
                    "annotations at the same time");
        }
        // 根据不同的注解,选择对应的metaHolderFactory, 创建MetaHolder, MetaHolder 里面包含了所有信息
        MetaHolderFactory metaHolderFactory = META_HOLDER_FACTORY_MAP.get(HystrixPointcutType.of(method));
        MetaHolder metaHolder = metaHolderFactory.create(joinPoint);
        // 根据 MetaHolder 构建调用命令
        HystrixInvokable invokable = HystrixCommandFactory.getInstance().create(metaHolder);
        // 命令类型: 异步 ASYNCHRONOUS, 同步 SYNCHRONOUS, 响应式(异步回调) OBSERVABLE;
        ExecutionType executionType = metaHolder.isCollapserAnnotationPresent() ?
                metaHolder.getCollapserExecutionType() : metaHolder.getExecutionType();

        // 根据不同的命令类型,执行命令,返回结果
        Object result;
        try {
            if (!metaHolder.isObservable()) {
                result = CommandExecutor.execute(invokable, executionType, metaHolder);
            } else {
                result = executeObservable(invokable, executionType, metaHolder);
            }
        } catch (HystrixBadRequestException e) {
            throw e.getCause();
        } catch (HystrixRuntimeException e) {
            throw hystrixRuntimeExceptionToThrowable(metaHolder, e);
        }
        return result;
    }
}

metaHolderFactory.create(joinPoint); —— 实现类:CommandMetaHolderFactory,CollapserMetaHolderFactory;

private static class CommandMetaHolderFactory extends MetaHolderFactory {
    @Override
    public MetaHolder create(Object proxy, Method method, Object obj, Object[] args, final ProceedingJoinPoint joinPoint) {
        HystrixCommand hystrixCommand = method.getAnnotation(HystrixCommand.class);
        ExecutionType executionType = ExecutionType.getExecutionType(method.getReturnType());
        MetaHolder.Builder builder = metaHolderBuilder(proxy, method, obj, args, joinPoint);
        if (isCompileWeaving()) {
            builder.ajcMethod(getAjcMethodFromTarget(joinPoint));
        }
        return builder.defaultCommandKey(method.getName())
                        .hystrixCommand(hystrixCommand)
                        .observableExecutionMode(hystrixCommand.observableExecutionMode())
                        .executionType(executionType)
                        .observable(ExecutionType.OBSERVABLE == executionType)
                        .build();
    }
}

HystrixCommandFactory.class ——  HystrixCommandFactory.getInstance().create(metaHolder);

public class HystrixCommandFactory {
    private static final HystrixCommandFactory INSTANCE = new HystrixCommandFactory();

    public static HystrixCommandFactory getInstance() {
        return INSTANCE;
    }
    
    // 根据 metaHolder 创建 HystrixInvokable 命令
    public HystrixInvokable create(MetaHolder metaHolder) {
        HystrixInvokable executable;
        if (metaHolder.isCollapserAnnotationPresent()) {
            executable = new CommandCollapser(metaHolder);
        } else if (metaHolder.isObservable()) {
            executable = new GenericObservableCommand(HystrixCommandBuilderFactory.getInstance().create(metaHolder));
        } else {
            executable = new GenericCommand(HystrixCommandBuilderFactory.getInstance().create(metaHolder));
        }
        return executable;
    }
}

 CommandExecutor.class ——  CommandExecutor.execute(invokable, executionType, metaHolder);

public static Object execute(HystrixInvokable invokable, ExecutionType executionType, MetaHolder metaHolder) throws RuntimeException {
    Validate.notNull(invokable);
    Validate.notNull(metaHolder);

    switch (executionType) {
        case SYNCHRONOUS: {
            // 强转成HystrixExecutable  同步执行
            return castToExecutable(invokable, executionType).execute();
        }
        case ASYNCHRONOUS: {
            // 强转成HystrixExecutable  异步执行
            HystrixExecutable executable = castToExecutable(invokable, executionType);
            // 如果有 fallback方法,且是异步执行,则执行并返回包装结果
            if (metaHolder.hasFallbackMethodCommand()
                    && ExecutionType.ASYNCHRONOUS == metaHolder.getFallbackExecutionType()) {
                return new FutureDecorator(executable.queue());
            }
            return executable.queue();
        }
        case OBSERVABLE: {
            // 强转成 HystrixObservable
            HystrixObservable observable = castToObservable(invokable);
            // 判断执行模式是不是急切/懒惰,来选择模式执行
            return ObservableExecutionMode.EAGER == metaHolder.getObservableExecutionMode() ? observable.observe() : observable.toObservable();
        }
        default:
            throw new RuntimeException("unsupported execution type: " + executionType);
    }
}

HystrixCommand的四种执行方式

方法同步/异步返回值
execute 同步 T
queue 异步 Future<T>
observe 异步 Observable<T>
toObservable 未执行 Observable<T>

HystrixCommand的四种执行方式的底层都是toObservable方法,而HystrixCommand.toObservable方法是Hystrix的关键流程

 

 

HystrixCommand.class

public R execute() {
    try {
        // 返回Feture对象(封装异步处理的结果)
        return queue().get();
    } catch (Exception e) {
        throw Exceptions.sneakyThrow(decomposeException(e));
    }
}

public Future<R> queue() {
    // toObservable转换为Observable,toBlocking转换为BlockingObservable, toFuture转换为Future,完成了Observable的创建和订阅
    final Future<R> delegate = toObservable().toBlocking().toFuture();
    
    final Future<R> f = new Future<R>() {
        // 通过cancel方法中断执行线程
        @Override
        public boolean cancel(boolean mayInterruptIfRunning) {
            if (delegate.isCancelled()) {
                return false;
            }
            // 如果 execution.isolation.thread.interruptOnFutureCancel = true(默认false)
            if (HystrixCommand.this.getProperties().executionIsolationThreadInterruptOnFutureCancel().get()) {
                // CAS 设置
                interruptOnFutureCancel.compareAndSet(false, mayInterruptIfRunning);
            }
            // 执行目标future的cancel
            final boolean res = delegate.cancel(interruptOnFutureCancel.get());
            if (!isExecutionComplete() && interruptOnFutureCancel.get()) {
                // 获取执行线程
                final Thread t = executionThread.get();
                if (t != null && !t.equals(Thread.currentThread())) {
                    // 中断线程
                    t.interrupt();
                }
            }
            return res;
        }
        ...省略
    };

    // 如果已经执行完毕了就返回
    if (f.isDone()) {
        try {
            f.get();
            return f;
        } catch (Exception e) {
            ... 异常处理
        }
    }
    return f;
}

toObservable() —— AbstractCommand.class

public Observable<R> toObservable() {
    final AbstractCommand<R> _cmd = this;

    // 命令执行完的回调操作 终止命令清理
    final Action0 terminateCommandCleanup = new Action0() {
        ...
    };

    // 将命令标记为已取消并存储延迟(除了标准清理)
    // 取消订阅时执行的操作
    final Action0 unsubscribeCommandCleanup = new Action0() {
        ...
    };

    // 执行命令时的回调
    final Func0<Observable<R>> applyHystrixSemantics = new Func0<Observable<R>>() {
        @Override
        public Observable<R> call() {
            if (commandState.get().equals(CommandState.UNSUBSCRIBED)) {
                return Observable.never();
            }
            return applyHystrixSemantics(_cmd);
        }
    };

    final Func1<R, R> wrapWithAllOnNextHooks = new Func1<R, R>() {
        ...
    };

    final Action0 fireOnCompletedHook = new Action0() {
        ...
    };

    // 创建Observable,设置各种处理操作
    return Observable.defer(new Func0<Observable<R>>() {
        @Override
        public Observable<R> call() {
            // 设置已启动标志
            if (!commandState.compareAndSet(CommandState.NOT_STARTED, CommandState.OBSERVABLE_CHAIN_CREATED)) {
                IllegalStateException ex = new IllegalStateException("This instance can only be executed once. Please instantiate a new instance.");
                throw new HystrixRuntimeException(FailureType.BAD_REQUEST_EXCEPTION, _cmd.getClass(), getLogMessagePrefix() + " command executed multiple times - this is not permitted.", ex, null);
            }

            commandStartTimestamp = System.currentTimeMillis();

            // 执行日志
            if (properties.requestLogEnabled().get()) {
                if (currentRequestLog != null) {
                    currentRequestLog.addExecutedCommand(_cmd);
                }
            }

            // 缓存处理
            final boolean requestCacheEnabled = isRequestCachingEnabled();
            final String cacheKey = getCacheKey();

            // 如果配置允许缓存,先试图从缓存获取,默认 false
            if (requestCacheEnabled) {
                HystrixCommandResponseFromCache<R> fromCache = (HystrixCommandResponseFromCache<R>) requestCache.get(cacheKey);
                if (fromCache != null) {
                    isResponseFromCache = true;
                    return handleRequestCacheHitAndEmitValues(fromCache, _cmd);
                }
            }

            // 创建Observable, applyHystrixSemantics() 来生成Observable
            Observable<R> hystrixObservable = Observable.defer(applyHystrixSemantics).map(wrapWithAllOnNextHooks);

            Observable<R> afterCache;

            // hystrixObservable 放入缓存
            if (requestCacheEnabled && cacheKey != null) {
                HystrixCachedObservable<R> toCache = HystrixCachedObservable.from(hystrixObservable, _cmd);
                HystrixCommandResponseFromCache<R> fromCache = (HystrixCommandResponseFromCache<R>) requestCache.putIfAbsent(cacheKey, toCache);
                if (fromCache != null) {
                    // another thread beat us so we'll use the cached value instead
                    toCache.unsubscribe();
                    isResponseFromCache = true;
                    return handleRequestCacheHitAndEmitValues(fromCache, _cmd);
                } else {
                    // we just created an ObservableCommand so we cast and return it
                    afterCache = toCache.toObservable();
                }
            } else {
                afterCache = hystrixObservable;
            }

            // 生命周期回调设置
            return afterCache
                    .doOnTerminate(terminateCommandCleanup)     // perform cleanup once (either on normal terminal state (this line), or unsubscribe (next line))
                    .doOnUnsubscribe(unsubscribeCommandCleanup) // perform cleanup once
                    .doOnCompleted(fireOnCompletedHook);
        }
    });
}

private Observable<R> applyHystrixSemantics(final AbstractCommand<R> _cmd) {
    // mark that we're starting execution on the ExecutionHook
    // if this hook throws an exception, then a fast-fail occurs with no fallback.  No state is left inconsistent
    executionHook.onStart(_cmd);

    // 是否允许请求,即断路器是否开启 ,这里也有好几种情况
    if (circuitBreaker.allowRequest()) {
        // 信号量获取
        final TryableSemaphore executionSemaphore = getExecutionSemaphore();
        final AtomicBoolean semaphoreHasBeenReleased = new AtomicBoolean(false);
        // 信号释放回调
        final Action0 singleSemaphoreRelease = new Action0() {
            @Override
            public void call() {
                if (semaphoreHasBeenReleased.compareAndSet(false, true)) {
                    executionSemaphore.release();
                }
            }
        };

        // 异常回调
        final Action1<Throwable> markExceptionThrown = new Action1<Throwable>() {
            @Override
            public void call(Throwable t) {
                eventNotifier.markEvent(HystrixEventType.EXCEPTION_THROWN, commandKey);
            }
        };

        // 获取信号,并返回对应的 Observable
        if (executionSemaphore.tryAcquire()) {
            try {
                /* used to track userThreadExecutionTime */
                executionResult = executionResult.setInvocationStartTime(System.currentTimeMillis());
                return executeCommandAndObserve(_cmd)
                        .doOnError(markExceptionThrown)
                        .doOnTerminate(singleSemaphoreRelease)
                        .doOnUnsubscribe(singleSemaphoreRelease);
            } catch (RuntimeException e) {
                return Observable.error(e);
            }
        } else {
            // 获取信号失败则降级
            return handleSemaphoreRejectionViaFallback();
        }
    } else {
        // 断路器已打开,直接降级
        return handleShortCircuitViaFallback();
    }
}

private Observable<R> executeCommandAndObserve(final AbstractCommand<R> _cmd) {
    final HystrixRequestContext currentRequestContext = HystrixRequestContext.getContextForCurrentThread();

    final Action1<R> markEmits = new Action1<R>() {
        ...
    };

    // 已完成回调
    final Action0 markOnCompleted = new Action0() {
        @Override
        public void call() {
            if (!commandIsScalar()) {
                long latency = System.currentTimeMillis() - executionResult.getStartTimestamp();
                eventNotifier.markCommandExecution(getCommandKey(), properties.executionIsolationStrategy().get(), (int) latency, executionResult.getOrderedList());
                eventNotifier.markEvent(HystrixEventType.SUCCESS, commandKey);
                executionResult = executionResult.addEvent((int) latency, HystrixEventType.SUCCESS);
                circuitBreaker.markSuccess();
            }
        }
    };

    // 各种失败回调处理
    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) {
                // HystrixBadRequestException 异常回调
                return handleBadRequestByEmittingError(e);
            } else {
                if (e instanceof HystrixBadRequestException) {
                    eventNotifier.markEvent(HystrixEventType.BAD_REQUEST, commandKey);
                    return Observable.error(e);
                }
                // 降级处理
                return handleFailureViaFallback(e);
            }
        }
    };

    final Action1<Notification<? super R>> setRequestContext = new Action1<Notification<? super R>>() {
        @Override
        public void call(Notification<? super R> rNotification) {
            setRequestContextIfNeeded(currentRequestContext);
        }
    };

    // 创建对应的 Observable,实现 线程隔离、请求发送 等操作
    Observable<R> execution;
    // 判断 超时监控功能是否打开
    if (properties.executionTimeoutEnabled().get()) {
        // HystrixObservableTimeoutOperator  转换对应的 Observable
        execution = executeCommandWithSpecifiedIsolation(_cmd).lift(new HystrixObservableTimeoutOperator<R>(_cmd));
    } else {
        execution = executeCommandWithSpecifiedIsolation(_cmd);
    }

    //设置回调
    return execution.doOnNext(markEmits)
            .doOnCompleted(markOnCompleted)
            .onErrorResumeNext(handleFallback)
            .doOnEach(setRequestContext);
}

private Observable<R> executeCommandWithSpecifiedIsolation(final AbstractCommand<R> _cmd) {
    // 线程隔离
    if (properties.executionIsolationStrategy().get() == ExecutionIsolationStrategy.THREAD) {
        //创建一个Observable
        return Observable.defer(new Func0<Observable<R>>() {
            @Override
            public Observable<R> call() {
                executionResult = executionResult.setExecutionOccurred();
                if (!commandState.compareAndSet(CommandState.OBSERVABLE_CHAIN_CREATED, CommandState.USER_CODE_EXECUTED)) {
                    return Observable.error(new IllegalStateException("execution attempted while in state : " + commandState.get().name()));
                }

                metrics.markCommandStart(commandKey, threadPoolKey, ExecutionIsolationStrategy.THREAD);

                // 该命令在包装线程中超时,将立即返回,并且不会增加任何计数器或其他此类逻辑
                if (isCommandTimedOut.get() == TimedOutStatus.TIMED_OUT) {
                    return Observable.error(new RuntimeException("timed out before executing run()"));
                }
                // 设置线程启动
                if (threadState.compareAndSet(ThreadState.NOT_USING_THREAD, ThreadState.STARTED)) {
                    //we have not been unsubscribed, so should proceed
                    HystrixCounters.incrementGlobalConcurrentThreads();
                    threadPool.markThreadExecution();
                    // store the command that is being run
                    endCurrentThreadExecutingCommand = Hystrix.startCurrentThreadExecutingCommand(getCommandKey());
                    executionResult = executionResult.setExecutedInThread();
                    /**
                        * If any of these hooks throw an exception, then it appears as if the actual execution threw an error
                        */
                    try {
                        executionHook.onThreadStart(_cmd);
                        executionHook.onRunStart(_cmd);
                        executionHook.onExecutionStart(_cmd);
                        //返回 Observable,这个函数最终会返回一个封装了我们的run()逻辑的Observable
                        return getUserExecutionObservable(_cmd);
                    } catch (Throwable ex) {
                        return Observable.error(ex);
                    }
                } else {
                    //command has already been unsubscribed, so return immediately
                    return Observable.error(new RuntimeException("unsubscribed before executing run()"));
                }
            }
        }).doOnTerminate(new Action0() {
            ...
        }).doOnUnsubscribe(new Action0() {
            ...
        }).subscribeOn(threadPool.getScheduler(new Func0<Boolean>() {
            ...
        }));
    } else {
        // 信号量隔离
        return Observable.defer(new Func0<Observable<R>>() {
            @Override
            public Observable<R> call() {
                executionResult = executionResult.setExecutionOccurred();
                if (!commandState.compareAndSet(CommandState.OBSERVABLE_CHAIN_CREATED, CommandState.USER_CODE_EXECUTED)) {
                    return Observable.error(new IllegalStateException("execution attempted while in state : " + commandState.get().name()));
                }

                metrics.markCommandStart(commandKey, threadPoolKey, ExecutionIsolationStrategy.SEMAPHORE);
                endCurrentThreadExecutingCommand = Hystrix.startCurrentThreadExecutingCommand(getCommandKey());
                try {
                    executionHook.onRunStart(_cmd);
                    executionHook.onExecutionStart(_cmd);
                    return getUserExecutionObservable(_cmd);
                } catch (Throwable ex) {
                    //If the above hooks throw, then use that as the result of the run method
                    return Observable.error(ex);
                }
            }
        });
    }
}
  • 判断是否允许发送请求,这基于 断路器 实现,如果 断路器 打开,则进行对应回调处理(失败或降级)
  • 如果 断路器 关闭,则进行请求,先获取 信号,获取失败则处理对应回调

  • 获取成功,则由方法 executeCommandAndObserve 创建对应的 Observable 实现 线程隔离、请求发送 等操作,同时注册了对应的 生命周期回调

 

参考博客 :https://blog.csdn.net/scau_cdx/article/details/106948905

 

posted @ 2021-04-01 18:02  柒月丶  阅读(332)  评论(0编辑  收藏  举报