接下来我们接着上次的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方法发生异常时执行,最终执行降级逻辑。
好嘛写不下去了,下次有时间在补补。