写代码的必选项:正确性、可读性、可测试性。可选项:性能、资源开销
–> 返回专栏总目录 <–
代码下载地址:https://github.com/f641385712/netflix-learning
前言
上篇文章 介绍了Hystrix事件计数器EventCounts和执行结果ExecutionResult
,它帮忙记录着执行过程中的事件计数以及各种时间、状态等结果。本文将要介绍命令执行过程中的核心接口,包括同步执行方法、异步执行方法以及基于RxJava的Observable
执行方式。
本篇内容仅会着眼于接口层面进行描述,从大的框架方面去掌握Hystrix的设计,这样后面仅需以一个“实现类”举例便可举一反三了。
正文
我们知道Hystrix是以命令模式执行目标方法的,也就是每个目标方法最终都会被封装成为一个command对象。但整体上它分为两个系列,它们的继承图表如下:
xxxCommand
系列:
xxxCollapser
系列:
二者实现的接口具有共通性,本篇文章将对这些核心接口进行解释说明。
HystrixInvokable
它是个纯标记接口,无任何方法:表示Hystrix commands
可以被invoke。
public interface HystrixInvokable<R> {
}
它虽然没有方法但带有一个泛型R:代表命令返回值。它有两个子接口:HystrixExecutable
和HystrixObservable
。
HystrixExecutable
HystrixCommand
和HystrixCollapser
均实现了此接口,以便于对它俩进行公共处理。
public interface HystrixExecutable<R> extends HystrixInvokable<R> {
// 同步执行,原理是:queue().get() 所以效果是同步的
public R execute();
// 异步执行,什么时候get由调用者决定。get的时候才会阻塞:获取结果或者错误
// 其实queue的原理是toObservable().toBlocking().toFuture()
public Future<R> queue();
// 异步执行。toObservable().subscribe(subject) subject=ReplaySubject
// 原理也是基于toObservable(),但是它是立马执行,且有回放的能力
public Observable<R> observe();
}
该接口正如其名:Executable
可执行的。提供同步执行方法,异步执行的Futrue,以及基于RxJava的Observable
可观察对象。正如注释中所言:它们的实现原理均是基于toObservable()
方法。该接口实现类有且仅有HystrixCommand
和HystrixCollapser
两个。
说明:
HystrixObservableCommand
和HystrixObservableCollapser
并不实现它,而是实现的HystrixObservable
接口。
HystrixObservable
同样的,它的目的也是为了抽取公共实现,它强调于HystrixObservable
。
可以看到,使用者能接触到的所有的子类都有实现于它。它强调Observable
,期望通过订阅式实现异步获取结果。
public interface HystrixObservable<R> extends HystrixInvokable<R> {
public Observable<R> observe();
public Observable<R> toObservable();
}
两个方法看似一样,都是得到一个Observable
,但有些许差异:
observe()
:提供饥饿模式的Observable实例:它会立马启动执行HystrixCommand#queue() / execute()
命令,并且执行回放ReplaySubject<R>
toObservable()
:提供Lazy/defer延迟模式的Observable实例:只有在订阅了Observable
之后,才惰性地开始执行命令
需要特别关心的是toObservable()
方法,它是所有的执行方法的基石,一切都源于它。
最后来看看xxxCmmand
系列实现的一个特殊接口:HystrixInvokableInfo
。
HystrixInvokableInfo
在xxxCommand
系列还有一个接口,它便是HystrixInvokableInfo
。从命名上看,它好似表示HystrixInvokable
的一些详细信息,而实际情况也确实如此。该接口提供大量的get类型的方法获取各种各样的值,而这些方法所需要的信息大多在执行结果ExecutionResult
这个POJO里。
说明:关于
ExecutionResult
的详解,请移步上篇文章
public interface HystrixInvokableInfo<R> {
// 获取各种key:
// CommandKey:命令的id
// CommandGroupKey:逻辑分组的key
// ThreadPoolKey:线程池分组的key。不指定默认使用CommandGroupKey的值
// CollapserKey:合并的id
HystrixCommandGroupKey getCommandGroup();
HystrixCommandKey getCommandKey();
HystrixThreadPoolKey getThreadPoolKey();
HystrixCollapserKey getOriginatingCollapserKey();
// 内部实际调用protected的AbstractCommand#getCacheKey()方法
// 就是把这个方法public掉的作用
String getPublicCacheKey()
// 获取command的指标信息(该类前面已经重点介绍过了)
HystrixCommandMetrics getMetrics();
// HystrixCommand的配置信息:非常多的属性可定制
// 实现:init初始化,一般来源于SPI机制
HystrixCommandProperties getProperties();
// 断路器是否打开:由HystrixCommandProperties配置以及circuitBreaker.isOpen()共同决定
boolean isCircuitBreakerOpen();
// 执行是否完成:commandState命令状态是否是TERMINAL状态:
boolean isExecutionComplete();
// 是否在隔离线程里执行的任务
// ExecutionResult#isExecutedInThread()
boolean isExecutedInThread();
// 是否执行成功。
// ExecutionResult#getEventCounts().contains(HystrixEventType.SUCCESS)
boolean isSuccessfulExecution();
// 实现:ExecutionResult#getEventCounts().contains(HystrixEventType.FAILURE)
boolean isFailedExecution();
// 若失败了,获取其异常信息
// 实现:executionResult.getException();
Throwable getFailedExecutionException();
// 是否是fallback了
// 实现:ExecutionResult#getEventCounts().contains(HystrixEventType.FALLBACK_SUCCESS)
boolean isResponseFromFallback();
// 实现:ExecutionResult#getEventCounts().contains(HystrixEventType.TIMEOUT)
boolean isResponseTimedOut();
// short-circuited:短路
// isCircuitBreakerOpen() == true并且结果来自于fallabck,这就叫直接短路了(根本不走你目标方法)
// 实现:ExecutionResult#getEventCounts().contains(HystrixEventType.SHORT_CIRCUITED)
boolean isResponseShortCircuited();
// 结果是否来自于缓存。若true,那么run()将不会被执行
boolean isResponseFromCache();
// 拒绝:响应是否是被拒绝后的回退(请注意:没有执行run方法)
// 包括线程池拒绝和信号量拒绝
// 实现:ExecutionResult#isResponseRejected()
boolean isResponseRejected();
boolean isResponseSemaphoreRejected()
boolean isResponseThreadPoolRejected()
// 执行过程中,所有被记录过的事件们(没被记录过的就木有)
// 实现ExecutionResult#getOrderedList()
List<HystrixEventType> getExecutionEvents()
// 命令执行过程中的发射次数。
// ExecutionResult#getEventCounts().getCount(HystrixEventType.EMIT);
int getNumberEmissions();
int getNumberFallbackEmissions();
int getNumberCollapsed();
// 此command实例的执行时间(以毫秒为单位),如果未执行,则为-1。
// 实现:ExecutionResult#getExecutionLatency
int getExecutionTimeInMilliseconds();
// 调用该command实例的run方法的时刻纳秒,如果没有执行,则为-1
// 实现:ExecutionResult#getCommandRunStartTimeInNanos
long getCommandRunStartTimeInNanos();
// EventCounts对象是对事件类型的的一个计数、统计
// 实现ExecutionResult#getEventCounts()
ExecutionResult.EventCounts getEventCounts()
}
虽说该接口实现类仅有HystrixCommand
和HystrixObservableCommand
,但它的所有的方法实现均在其父类AbstractCommand
里,并且大多数都委托给执行结果ExecutionResult
去完成,这就是为何要有上篇文章的原因喽。
- 该接口所有的方法实现均在
AbstractCommand
抽象类里,其子类HystrixCommand/HystrixObservableCommand
均无需关心 - 大多数方法都是获取执行完成后的结果数据/状态数据,所以大多数方法都是委托给
ExecutionResult
去实现。
总结
关于Hystrix执行过程核心接口:HystrixExecutable、HystrixObservable和HystrixInvokableInfo就介绍到这了,本文的目的有两个:
- 面向接口理解Hystrix的设计框架,更全面的掌握Hystrix的架构设计
- 详解
HystrixInvokableInfo
接口,和ExecutionResult
产生联系
声明
原创不易,码字不易,多谢你的点赞、收藏、关注。把本文分享到你的朋友圈是被允许的,但拒绝抄袭
。你也可【左边扫码/或加wx:fsx641385712】邀请你加入我的 Java高工、架构师 系列群大家庭学习和交流。
- [享学Netflix] 一、Apache Commons Configuration:你身边的配置管理专家
- [享学Netflix] 二、Apache Commons Configuration事件监听机制及使用ReloadingStrategy实现热更新
- [享学Netflix] 三、Apache Commons Configuration2.x全新的事件-监听机制
- [享学Netflix] 四、Apache Commons Configuration2.x文件定位系统FileLocator和FileHandler
- [享学Netflix] 五、Apache Commons Configuration2.x别样的Builder模式:ConfigurationBuilder
- [享学Netflix] 六、Apache Commons Configuration2.x快速构建工具Parameters和Configurations
- [享学Netflix] 七、Apache Commons Configuration2.x如何实现文件热加载/热更新?
- [享学Netflix] 八、Apache Commons Configuration2.x相较于1.x使用上带来哪些差异?
- [享学Netflix] 九、Archaius配置管理库:初体验及基础API详解
- [享学Netflix] 十、Archaius对Commons Configuration核心API Configuration的扩展实现
- [享学Netflix] 十一、Archaius配置管理器ConfigurationManager和动态属性支持DynamicPropertySupport
- [享学Netflix] 十二、Archaius动态属性DynamicProperty原理详解(重要)
- [享学Netflix] 十三、Archaius属性抽象Property和PropertyWrapper详解
- [享学Netflix] 十四、Archaius如何对多环境、多区域、多云部署提供配置支持?
- [享学Netflix] 十五、Archaius和Spring Cloud的集成:spring-cloud-starter-netflix-archaius
- [享学Netflix] 十六、Hystrix断路器:初体验及RxJava简介
- [享学Netflix] 十七、Hystrix属性抽象以及和Archaius整合实现配置外部化、动态化
- [享学Netflix] 十八、Hystrix配置之:全局配置和实例配置
- [享学Netflix] 十九、Hystrix插件机制:SPI接口介绍和HystrixPlugins详解
- [享学Netflix] 二十、Hystrix跨线程传递数据解决方案:HystrixRequestContext
- [享学Netflix] 二十一、Hystrix指标数据收集(预热):滑动窗口算法(附代码示例)
- [享学Netflix] 二十二、Hystrix事件源与事件流:HystrixEvent和HystrixEventStream
- [享学Netflix] 二十三、Hystrix桶计数器:BucketedCounterStream
- [享学Netflix] 二十四、Hystrix在滑动窗口内统计:BucketedRollingCounterStream、HealthCountsStream
- [享学Netflix] 二十五、Hystrix累计统计流、分发流、最大并发流、配置流、功能流(附代码示例)
- [享学Netflix] 二十六、Hystrix指标数据收集器:HystrixMetrics(HystrixDashboard的数据来源)
- [享学Netflix] 二十七、Hystrix何为断路器的半开状态?HystrixCircuitBreaker详解
- [享学Netflix] 二十八、Hystrix事件计数器EventCounts和执行结果ExecutionResult