Hystrix源码分析二

接下来我们接着上次的toObservable开始讲解

我们可以看到toObservable()返回的是一个Observable对象。

看来用的响应式编程。简单来说,运用了大量的观察者模式,并且比观察者模式还要复杂。 observalble被观察者,observer观察者,当被观察者发生变化会通知观察者。

public Observable<R> toObservable() {
    //_cmd 指向当前命令对象
    final AbstractCommand<R> _cmd = this;
   // 命令执行结束后的清理者
    final Action0 terminateCommandCleanup = new Action0() {...};
	 // 取消订阅时处理者
    final Action0 unsubscribeCommandCleanup = new Action0() {...};
    
    //这个对象是一个被观察者。返回的是一个applyHystrixSemantics对象。
    //应用Hystrix语义 重点:Hystrix 核心逻辑: 断路器、隔离
    final Func0<Observable<R>> applyHystrixSemantics = new Func0<Observable<R>>() {
        @Override
        public Observable<R> call() {// //call方法 就是,就是一个对应一个观察者,每一个观察都有对应的一个动作。当被观察者发生变化后,执行这个动作。
            // commandState 处于 UNSUBSCRIBED未订阅 时,不执行命令
            if (commandState.get().equals(CommandState.UNSUBSCRIBED)) {
                //返回一个从不发送任何项目或通知到{@link Observer}的Observable
                return Observable.never();
            }
            // 获得 执行Observable
            return applyHystrixSemantics(_cmd);
        }
    };

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

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

最终上面的方法首先创建了一些清理的处理逻辑的观察者,但都没有直接调用

最终执行的是Observable.defer()。这个是被观察者,这个返回的就是我们的观察者

调用OnSubscribeDefer().call()方法,就是调用applyHystrixSemantics.call()

//Observable.defer() 就是说:必须有观察者订阅了我是,我才开始发射数据。
//而defer()的参数是个Func0,是一个会返回Observable的执行实体
//Func0 就是 :applyHystrixSemantics
return Observable.defer(new Func0<Observable<R>>() {//使用传入 observableFactory 参数,生成动态的 Observable 。
        @Override
        public Observable<R> call() {
             //this is a stateful object so can only be used once
            //是否第一次执行
            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()) {
                // log this command execution regardless of what happened
                if (currentRequestLog != null) {
                    currentRequestLog.addExecutedCommand(_cmd);
                }
            }
			// 缓存开关、缓存KEY
            final boolean requestCacheEnabled = isRequestCachingEnabled();
            final String cacheKey = getCacheKey();
			
             // 优先从缓存中获取
            //  如果请求结果缓存这个特性被启用,并且缓存命中,则缓存的回应会立即通过一个 Observable对象的形式返回。
            if (requestCacheEnabled) {
                HystrixCommandResponseFromCache<R> fromCache = (HystrixCommandResponseFromCache<R>) requestCache.get(cacheKey);
                //如果缓存不为空,取出值,直接返回
                if (fromCache != null) {
                    isResponseFromCache = true; // 标记 从缓存中结果
                    return handleRequestCacheHitAndEmitValues(fromCache, _cmd);
                }
            }
			//当缓存特性未开启,或者缓存未命中时
           // // 使用上面的Func0:applyHystrixSemantics 来创建Observable
            Observable<R> hystrixObservable =Observable.defer(applyHystrixSemantics)
                            				.map(wrapWithAllOnNextHooks);
			// 获得 缓存Observable
            Observable<R> afterCache;

            //将结果分装至缓存 
           
            if (requestCacheEnabled && cacheKey != null) {
                // 包装以进行缓存
                HystrixCachedObservable<R> toCache = HystrixCachedObservable.from(hystrixObservable, _cmd);
                //创建【订阅了执行命令的 Observable】的 HystrixCommandResponseFromCache 。
                //并添加到 requestCache
                HystrixCommandResponseFromCache<R> fromCache = (HystrixCommandResponseFromCache<R>) requestCache.putIfAbsent(cacheKey, toCache);
                //多个线程添加时,只有一个线程添加成功。
                if (fromCache != null) {// 添加失败   失败的线程
                    //调用unsubscribe() 方法,取消 HystrixCommandResponseFromCache 的订阅。
                    toCache.unsubscribe();
                    isResponseFromCache = true;// 标记 从缓存中结果   
                    //处理请求缓存命中和发射值
                    return handleRequestCacheHitAndEmitValues(fromCache, _cmd);
                } else {// 添加成功
                    // 获得缓存 Observable
                    afterCache = toCache.toObservable();
                }
            } else {
                //当缓存特性未开启,使用执行命令 Observable 。
                afterCache = hystrixObservable;
            }
			// 为Observable绑定几个特定事件的处理者,这都是上门创建的Action0
            return afterCache
                    .doOnTerminate(terminateCommandCleanup)     
                    .doOnUnsubscribe(unsubscribeCommandCleanup) 
                    .doOnCompleted(fireOnCompletedHook);
        }
    });
}

当缓存特性未开启,或者缓存未命中时,使用 applyHystrixSemantics 传入 Observable#defer(...) 方法,声明执行命令的 Observable。

public static <T> Observable<T> defer(Func0<Observable<T>> observableFactory) {
    //入参设置为OnSubscribeDefer对象,使用传入 `observableFactory` 参数,生成动态的 Observable
    return unsafeCreate(new OnSubscribeDefer<T>(observableFactory));
}

最后执行订阅

public static <T> Observable.OnSubscribe<T> onCreate(Observable.OnSubscribe<T> onSubscribe) {
    Func1<Observable.OnSubscribe, Observable.OnSubscribe> f = onObservableCreate;
    if (f != null) {
        return f.call(onSubscribe);//订阅时推送事件
    }
    return onSubscribe;
}

f.call(onSubscribe);调用OnSubscribeDefer的call(),最终调用applyHystrixSemantics.call()

public final class OnSubscribeDefer<T> implements OnSubscribe<T> {
    final Func0<? extends Observable<? extends T>> observableFactory;

    public OnSubscribeDefer(Func0<? extends Observable<? extends T>> observableFactory) {
        this.observableFactory = observableFactory;
    }

    @Override
    public void call(final Subscriber<? super T> s) {
        Observable<? extends T> o;
        try {
            //调用applyHystrixSemantics.call()
            //返回applyHystrixSemantics(_cmd);
            o = observableFactory.call();
        } catch (Throwable t) {
            Exceptions.throwOrReport(t, s);
            return;
        }
        //applyHystrixSemantics的返回的Observable进行非安全订阅
        o.unsafeSubscribe(Subscribers.wrap(s));
    }

}
public final Subscription unsafeSubscribe(Subscriber<? super T> subscriber) {
    try {
        // 默认啥都不干
        subscriber.onStart();
        // 钩子拦截和/或装饰
        //什么都不做直接返回入参的onSubscribe对象(toObservable创建返回的可观察者对象)。
        RxJavaHooks.onObservableStart(this, onSubscribe).call(subscriber);
        
        return RxJavaHooks.onObservableReturn(subscriber);
    } catch (Throwable e) {
        ...
            //取消订阅
        return Subscriptions.unsubscribed();
    }
}

之后我们回到applyHystrixSemantics方法中:

创建 applyHystrixSemantics 变量,代码如下 :

final Func0<Observable<R>> applyHystrixSemantics = new Func0<Observable<R>>() {
            @Override
            public Observable<R> call() {
                 commandState 处于 UNSUBSCRIBED(未订阅) 时,不执行命令
                if (commandState.get().equals(CommandState.UNSUBSCRIBED)) {
                    return Observable.never();
                }
                //调用 #applyHystrixSemantics(...) 方法,获得执行 Observable
                return applyHystrixSemantics(_cmd);
            }
        };

我们先看下Observable.never()里不发送任何项目或通知的Observable的创建

public enum NeverObservableHolder implements OnSubscribe<Object> {
    INSTANCE
    ;
    static final Observable<Object> NEVER = Observable.unsafeCreate(INSTANCE);
    //返回永不可观察的类型校正的单例实例。
    @SuppressWarnings("unchecked")
    public static <T> Observable<T> instance() {
        return (Observable<T>)NEVER;
    }
    @Override
    public void call(Subscriber<? super Object> child) {
        // deliberately no op
    }
}

我们可以看到NeverObservable的持有人call方法是空的,所以它执行call方法也是空的,最后不会去通知任何人

#applyHystrixSemantics(...) 方法,代码如下 :

private Observable<R> applyHystrixSemantics(final AbstractCommand<R> _cmd) {
    //保存当前Command
    executionHook.onStart(_cmd);

  	// 如果断路器是打开的,那么进入fallback处理流程;如果断路器是关闭的,那么进入下一步。
    if (circuitBreaker.allowRequest()) {
        // // 获得 信号量
        final TryableSemaphore executionSemaphore = getExecutionSemaphore();
        //信号量已发布
        final AtomicBoolean semaphoreHasBeenReleased = new AtomicBoolean(false);
         信号量释放Action
        final Action0 singleSemaphoreRelease = new Action0() {
            @Override
            public void call() {
                if (semaphoreHasBeenReleased.compareAndSet(false, true)) {
                    executionSemaphore.release();
                }
            }
        };
		//【Hystrix 事件机制】
        final Action1<Throwable> markExceptionThrown = new Action1<Throwable>() {
            @Override
            public void call(Throwable t) {
                //do no thing
                eventNotifier.markEvent(HystrixEventType.EXCEPTION_THROWN, commandKey);
            }
        };
		// 信号量 获得 如果此Command相关的线程池的请求队列或信号量已满,那么进入fallback处理流程,否则进入下一步
        if (executionSemaphore.tryAcquire()) {
            try {
                标记 executionResult 调用开始时间
                executionResult = executionResult.setInvocationStartTime(System.currentTimeMillis());
                //执行命令并返回可观察对象executeCommandAndObserve。
                return executeCommandAndObserve(_cmd)
                        .doOnError(markExceptionThrown)
                        .doOnTerminate(singleSemaphoreRelease)
                        .doOnUnsubscribe(singleSemaphoreRelease);
            } catch (RuntimeException e) {
                //若发生异常,调用 Observable#error(Exception) 方法返回 Observable 。
                return Observable.error(e);
            }
        } else {
            //信号量机制拒绝 走的降级逻辑
            return handleSemaphoreRejectionViaFallback();
        }
    } else {//熔断打开 走的降级逻辑
        return handleShortCircuitViaFallback();
    }
}

首先判断断路器是否允许执行

@Override
public boolean allowRequest() {
    //是否打开
    if (properties.circuitBreakerForceOpen().get()) {
        //断路器打开  不允许请求
        return false;
    }
    if (properties.circuitBreakerForceClosed().get()) {
        //我们仍然希望允许isOpen()执行其计算,因此我们可以模拟正常行为
        isOpen();
        //断路器关闭,可以执行
        return true;
    }
    //断路器关闭,或是半开(允许单项测试),允许执行
    return !isOpen() || allowSingleTest();
}

Hystrix提供了一个信号量限流器,限制进入熔断器最大并发数,可以控制请求下游的并发量,如果超过这个阈值,会被降级处理。

在THREAD模式下executionSemaphore的实现是TryableSemaphoreNoOp,其tryAcquire方法始终返回true

@Override
public boolean tryAcquire() {
    int currentCount = count.incrementAndGet();//计数  先加一
    if (currentCount > numberOfPermits.get()) { //判断是否大于最大允许信号量
        count.decrementAndGet();//大于就 减一
        return false;//请求失败
    } else {
        return true;//请求成功
    }
}

信号量和断路器都允许执行后,执行executeCommandAndObserve(),处理隔离策略和各种Fallback.

private Observable<R> executeCommandAndObserve(final AbstractCommand<R> _cmd) {
    final HystrixRequestContext currentRequestContext = HystrixRequestContext.getContextForCurrentThread();
	//创建markEmits、markOnCompleted、handleFallback、setRequestContext 动作
    final Action1<R> markEmits = new Action1<R>() {...};

    final Action0 markOnCompleted = new Action0() {...};
	// 失败回退逻辑 Func1
    final Func1<Throwable, Observable<R>> handleFallback = new Func1<Throwable, Observable<R>>() {...};

    final Action1<Notification<? super R>> setRequestContext = new Action1<Notification<? super R>>() {...};

    Observable<R> execution;
    //从配置文件中获取线程的隔离的策略。
    if (properties.executionTimeoutEnabled().get()) {//启动执行超时机制时
        //使用特殊隔离模式执行命令executeCommandWithSpecifiedIsolation,创建一个可观察对象并返回
        execution = executeCommandWithSpecifiedIsolation(_cmd)
                .lift(new HystrixObservableTimeoutOperator<R>(_cmd));
    } else {
        execution = executeCommandWithSpecifiedIsolation(_cmd);
    }

    return execution.doOnNext(markEmits)
            .doOnCompleted(markOnCompleted)
        	// 绑定Fallback的处理者
            .onErrorResumeNext(handleFallback)
            .doOnEach(setRequestContext);
}

我们来看看executeCommandWithSpecifiedIsolation(_cmd)如何使用指定的隔离执行命令

private Observable<R> executeCommandWithSpecifiedIsolation(final AbstractCommand<R> _cmd) {
    //判断隔离策略,如果是Semaphore 信号量则在当前线程上执行,否则进入线程分配逻辑
    if (properties.executionIsolationStrategy().get() == ExecutionIsolationStrategy.THREAD) {
        
        return Observable.defer(new Func0<Observable<R>>() {
            @Override
            public Observable<R> call() {
                //标记 executionResult 执行已发生
                executionResult = executionResult.setExecutionOccurred();
                //更改HystrixCommand的状态 USER_CODE_EXECUTED,若设置失败,调用 Observable#error(Exception) 方法返回 Observable 。 
                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);
				//判断HystrixCommand超时状态,如果已经超时则抛出异常
                if (isCommandTimedOut.get() == TimedOutStatus.TIMED_OUT) {
                  
                    return Observable.error(new RuntimeException("timed out before executing run()"));
                }
                //更改当前command的线程执行状态为 STARTED
                if (threadState.compareAndSet(ThreadState.NOT_USING_THREAD, ThreadState.STARTED)) {
                    
                    HystrixCounters.incrementGlobalConcurrentThreads();
                    threadPool.markThreadExecution();
                    
                    endCurrentThreadExecutingCommand = Hystrix.startCurrentThreadExecutingCommand(getCommandKey());
                    // 标记 executionResult 使用线程执行
                    executionResult = executionResult.setExecutedInThread();
                   
                    try {
                        executionHook.onThreadStart(_cmd);
                        executionHook.onRunStart(_cmd);
                        executionHook.onExecutionStart(_cmd);
                        //调用 getUserExecutionObservable 执行具体逻辑   获得 执行Observable
                        return getUserExecutionObservable(_cmd);
                    } catch (Throwable ex) {
                        return Observable.error(ex);
                    }
                } else {
                    //设置 threadState 为 ThreadState.STARTED 失败,执行命令此时已经被取消,调用 Observable#empty() 方法返回 Observable 。
                    return Observable.error(new RuntimeException("unsubscribed before executing run()"));
                }
            }
        }).doOnTerminate(new Action0() {//添加终止时Action
            //当Observale执行完毕后(HystrixCommand可能失败也可能执行成功),此时的线程状态可能有两种分别是 STARTED 和 NOT_USING_THREAD , 然后更改线程状态为 TERMINAL
            @Override
            public void call() {
                if (threadState.compareAndSet(ThreadState.STARTED, ThreadState.TERMINAL)) {
                    handleThreadEnd(_cmd);
                }
                if (threadState.compareAndSet(ThreadState.NOT_USING_THREAD, ThreadState.TERMINAL)) {
                   
                }
                
            }
        }).doOnUnsubscribe(new Action0() {//添加取消订阅时Action
            //当Observable被取消订阅,更改线程状态为 TERMINAL
            @Override
            public void call() {
                if (threadState.compareAndSet(ThreadState.STARTED, ThreadState.UNSUBSCRIBED)) {
                    handleThreadEnd(_cmd);
                }
                if (threadState.compareAndSet(ThreadState.NOT_USING_THREAD, ThreadState.UNSUBSCRIBED)) {
                   
                }
               
            }
        }).subscribeOn(threadPool.getScheduler(new Func0<Boolean>() {// 指定 Observable 自身在哪个调度器上执行 
            @Override
            public Boolean call() {
                //HystrixCommand的状态是否为TIMED_OUT
                return properties.executionIsolationThreadInterruptOnTimeout().get() && _cmd.isCommandTimedOut.get() == TimedOutStatus.TIMED_OUT;
            }
        }));
    } else {//如果是信号量隔离
        return Observable.defer(new Func0<Observable<R>>() {
            @Override
            public Observable<R> call() {
                // // 标记 executionResult 执行已发生
                executionResult = executionResult.setExecutionOccurred();
                // 设置 commandState 为 USER_CODE_EXECUTED
                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);
                    //调用 getUserExecutionObservable 执行具体逻辑 获得 执行Observable
                    return getUserExecutionObservable(_cmd);  
                } catch (Throwable ex) {
                 
                    return Observable.error(ex);
                }
            }
        });
    }
}

根据执行隔离策略不同,创建不同的【执行命令 Observable】。仔细对比下,大体逻辑都是相同的,差别在于执行隔离策略Thread 时,使用 RxJava Scheduler 以及对线程的处理。

#getUserExecutionObservable(…)
private Observable<R> getUserExecutionObservable(final AbstractCommand<R> _cmd) {
    Observable<R> userObservable;

    try {
        //创建【执行命令 Observable】
        userObservable = getExecutionObservable();
    } catch (Throwable ex) {
       //run()方法是用户提供的实现,因此可以抛出该异常,而不是使用Observable.onError ,因此我们在此处将其捕获并将其转换为Observable.erro
        userObservable = Observable.error(ex);
    }

    return userObservable
            .lift(new ExecutionHookApplication(_cmd))
            .lift(new DeprecatedOnRunHookApplication(_cmd));
}
#getExecutionObservable()
@Override
final protected Observable<R> getExecutionObservable() {
    //调用 Observable#defer(Func0<Observable<R>) 方法,创建【执行命令 Observable】。
    return Observable.defer(new Func0<Observable<R>>() {
        @Override
        public Observable<R> call() {
            try {
                //调用 #run() 方法,运行正常执逻辑。通过 Observable#just(...) 方法,返回创建【执行命令 Observable】。
                return Observable.just(run());
            } catch (Throwable ex) {
                return Observable.error(ex);
            }
        }
    }).doOnSubscribe(new Action0() {//调用 #doOnSubscribe(...) 方法,添加 Action 。
        //该操作记录执行线程( executionThread ) 。executionThread 用于 HystrixCommand#queue() 方法,返回的 Future 结果,可以调用 Future#cancel(Boolean) 方法
        @Override
        public void call() {
           //保存我们订阅的线程,以便以后需要时可以中断它
            executionThread.set(Thread.currentThread());
        }
    });
}

最终回到了HystrixCommand的中,run方法终于执行了。run方法执行之后,如果正常返回、抛出异常、或者其它情况,都需要对应的后续处理,这时之前executeCommandAndObserve方法中定义的Action,就开始起作用了。

回到executeCommandAndObserve

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

markEmits回调:run方法正常返回时执行,主要记录执行耗时;触发执行成功的通知事件,可以通过扩展插件做更多事情;如果当前是熔断状态,则关闭熔断。handleFallback:run方法发生异常时执行,最终执行降级逻辑。

好嘛写不下去了,下次有时间在补补。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值