HystrixCommandAspect
1.根据入参连接点joinPoint获取方法method,并且校验不能为空
2.校验方法method不能既使用HystrixCommand注解,同时又使用HystrixCollapser 注解
3.然后获取工厂metaHolderFactory,创建出metaHolder
4.然后创建出invokable
5.获取执行类型executionType
6.调用CommandExecutor.execute执行,并且返回结果
分成同步,异步,和Observable
++++++++++++++++++++++++++++++++++++++++++++++++++++
具体的执行细节
执行分成同步,异步
熔断后执行fallback
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
commandKey:每个command都有对应的commandKey可以认为是command的名字,默认情况下(注解未指定),命令名称来源于切入方法的方法名(method.getName())。自定义使用HystrixCommandKey.Factory.asKey("HelloWorld"),说实话感觉没啥用,不需要自定义。
groupKey:Hystrix使用命令分组将一起的命令进行管理,比如报告、警报、仪表盘或组/库。默认情况下(注解未指定),名称来源于切入方法所属类的类名名(obj.getClass().getSimpleName()),Hystrix使用 HystrixCommandGroupKey 来定义命令线程池,除非单独定义线程池。
验证:commandKey和groupKey可以看源码CommandMetaHolderFactory.create以及HystrixCommandBuilderFactory中的createGenericSetterBuilder方法。
threadPoolKey:线程池主要体现是用于监测、指标发布、缓存和其他此类用途的HystrixThreadPool。当隔离方式为线程时,有隔离的作用。AbstractCommand.threadPool通过HystrixThreadPool.getInstance获取。
具有相同的threadPoolKey的使用同一个线程池,如果注解未指定threadPoolKey,则使用groupKey作为HystrixThreadPoolKey。
《Spring Cloud 微服务实战》推荐:通常情况下,尽量通过 HystrixThreadPoolKey 的方式来指定线程池的划分, 而不是通过组名的默认方式实现划分, 因为多个不同的命令可能 从业务逻辑上来看属于同 一个组, 但是往往从实现本身上需要跟其他命令进行隔离
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
简单的的来看就是:创建一个Observable,然后绑定各种事件对应的处理者,各类doOnXXXX,表示发生XXX事件时做什么事情。代码如下
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
当缓存特性未开启,或者缓存未命中时,使用 applyHystrixSemantics
传入 Observable#defer(...)
方法,声明执行命令的 Observable。
调用 #applyHystrixSemantics(...)
方法,获得执行 Observable
线程池隔离: 保证tomcat线程不会卡死,可以快速返回,执行别的;使用Hystrix自己的线程去执行调用
信号量隔离:是直接让tomcat应用线程去调用依赖服务
线程池隔离:需要对调用捕获timeout超时异常
信号量隔离: 不需要捕获timeout超时异常
信号量隔离的方式是限制了总的并发数,每一次请求过来,请求线程和调用依赖服务的线程是同一个线程,那么如果不涉及远程RPC调用(没有网络开销)则使用信号量来隔离,更为轻量,开销更小。
信号量隔离:只能是同步,不能支持异步。但是消耗资源小
线程池隔离:资源消耗大,单独起Hystrix线程去执行。为了捕获超时异常
5.1 HystrixThreadPoolDefault
com.netflix.hystrix.HystrixThreadPool.HystrixThreadPoolDefault
,Hystrix 线程池实现类。
根据 threadPoolKey
先从 threadPool
获取已创建的 HystrixThreadPool ;获取不到,创建对应的 HystrixThreadPool 返回,并添加到 threadPool
。
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Hystrix 源码解析 —— 命令执行(三)之执行超时
2. HystrixObservableTimeoutOperator
Hystrix 源码解析 —— 请求执行(四)之失败回退逻辑
当命令执行超时时,失败回退逻辑使用的是 HystrixTimer 的线程池。