关于hystrix:hystrix源码分析二
先温习下Hystrix的整体流程 结构一个 HystrixCommand或HystrixObservableCommand对象,用于封装申请,并在构造方法配置申请被执行须要的参数;执行命令,Hystrix提供了4种执行命令的办法判断是否应用缓存响应申请,若启用了缓存,且缓存可用,间接应用缓存响应申请。Hystrix反对申请缓存,但须要用户自定义启动;判断熔断器是否关上,如果关上,执行第8步;判断线程池/队列/信号量是否已满,已满则执行第8步;执行HystrixObservableCommand.construct()或HystrixCommand.run(),如果执行失败或者超时,执行第8步;否则,跳到第9步;统计熔断器监控指标;走Fallback备用逻辑返回申请响应一,execute办法剖析承接上篇,在HystrixCommandAspect这个切面里会创立HystrixInvokable对象,进而执行。 Object result; try { if (!metaHolder.isObservable()) { result = CommandExecutor.execute(invokable, executionType, metaHolder); } else { result = executeObservable(invokable, executionType, metaHolder); } } catch (HystrixBadRequestException e) { throw e.getCause() != null ? e.getCause() : e; } catch (HystrixRuntimeException e) { throw hystrixRuntimeExceptionToThrowable(metaHolder, e); }这里就来剖析下execute的流程。Hystrix是反对同步,异步,察看这个三个模式的,咱们只看同步,调用链路是:HystrixCommand.execute() -> queue() -> toObservable() public Observable<R> toObservable() { .... 一些action的定义 .... final Func0<Observable<R>> applyHystrixSemantics = new Func0<Observable<R>>() { public Observable<R> call() { if(this.commandState.get()).equals(AbstractCommand.CommandState.UNSUBSCRIBED)){ return Observable.never() }else{ applyHystrixSemantics(AbstractCommand.this); } } }; ... return Observable.defer(new Func0<Observable<R>>() { public Observable<R> call() { ...判断是否开启缓存,对应上整体流程的3步... boolean requestCacheEnabled = AbstractCommand.this.isRequestCachingEnabled(); String cacheKey = AbstractCommand.this.getCacheKey(); if (requestCacheEnabled) { //拿去缓存,如果存在缓存的话,间接返回 HystrixCommandResponseFromCache<R> fromCache = (HystrixCommandResponseFromCache<R>) requestCache.get(cacheKey); if (fromCache != null) { isResponseFromCache = true; return handleRequestCacheHitAndEmitValues(fromCache, _cmd); } } Observable<R> hystrixObservable = Observable.defer(applyHystrixSemantics).map(wrapWithAllOnNextHooks); Observable afterCache; if (requestCacheEnabled && cacheKey != null) { ... 缓存后续的一些判断..... } else { afterCache = hystrixObservable; } return afterCache.doOnTerminate(terminateCommandCleanup) .doOnUnsubscribe(unsubscribeCommandCleanup) .doOnCompleted(fireOnCompletedHook); } });}call外面的办法主要用途: ...