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