十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
本篇内容主要讲解“如何理解SpringCloud Hystrix源码解析”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“如何理解SpringCloud Hystrix源码解析”吧!
我们提供的服务有:成都网站设计、网站建设、微信公众号开发、网站优化、网站认证、望奎ssl等。为数千家企事业单位解决了网站和推广的问题。提供周到的售前咨询和贴心的售后服务,是有科学管理、有技术的望奎网站制作公司
SpringCloud Hystrix源码解析
看本篇之前请看
五分钟学会 Spring Cloud Hystrix:服务容错保护(小白必看,一看就会系列教程)
使用Hystrix 后的远程调用流程如下:
1 )构建HystrixCommand 或者Hys trixObservableCommand 对象。
2 )执行命令。
3 )检查是否有相同命令执行的缓存。
4 )检查断路器是否打开。
5 )检查线程池或者信号量是否被消耗完。
6 )调用Hystri xOb servabl eCommand#construct 或Hystri xCommand#run 执行被封装的远程调用逻辑。
7 )计算链路的健康情况。
8 )在命令执行失败时获取Fallback 逻辑。
9 )返回成功的Observable 。
@HystrixCommand 注解
在基础应用中我们使用@HystrixCommand 注解来包装需要保护的远程调用方法。首先查看该注解的相关属性,代码如下所示:
/ / HystrixComrnand . Java@Target ( { Element Type . METHOD})@Retentio口( RetentionPolicy . RUNTIME)@Inherited@Document ed pu b l 工C @int er face Hys t r ixComrnand { //命令分组键用于报告、预警以及面板展示 //默认为被注解方法的运行时类名 String groupKey() default//日ystr 工X 的命令键,用于区分不同的注解方法 //默认为注解方法的名称 String commandKey () default//线程池键用来指定命令执行的HystrixTh readPool Str 工ng threadPoolKey () defaul t ”” ;第6 章断路器Hystrix •!• 125//指定Fallback方法名, Fallback方法也可以被HystrixCommand注解 String fallbackMethod () default//自定义命令的相关配置 HystrixProperty[) commandProperties() default { } ;//自定义线程池的相关配置 HystrixProperty [ J threadPoolProperties () default { } ;//定义忽略哪些异常 Class ext ends Throwable>[) ignoreExceptions() default { } ;//默认的fallback String defaultFallback() default “”;}
一般来说,对于HystrixCommand 的配置,仅需要关注fallbac灿fothod 方法,当然如果对命令和线程池有特定需要,可以进行额外的配置。除了@HystrixCommand 还有一个@Hystrix Collapser 注解用于请求合并操作,但是需要与@HystrixCommand 结合使用, 批量操作的方法必须被@HystrixCommand 注解。
HystrixCommandAspect 切面
被注解修饰的方法将会被HystrixCommand 包装执行,在Hystrix 中通过Aspectj 切面的方式来将被注解修饰的方法进行封装调用。
1 )通过MetaHolderFactory 构建出被注解修饰方法中用于构建HystrixCommand 必要信息集合类MetaHolder 。
2 )根据MetaHolder 通过HystrixCommandFactory 构建出合适的HystrixCommand 。
3 )委托CommandExecutor 执行HystrixCommand ,得到结果。
MetaHolder 持有用于构建HystrixCommand 和与被包装方法相关的必要信息,如被注解的方法、失败回滚执行的方法和默认的命令键等属性。
//MetaHolder . Java@Immutablepublic final class MetaHolder { private fina l Method method ; //被注解的方法 pr 工vate final Method cacheKeyMethod ;pri vate final Method ajcMethod ;private final Method fallbackMethod ; //失败回滚执行的方法private final String defaultGroupKey ; // 默认的group键private final String defaultCommandKey ; //默认的命令键private f inal String defaultCollapserKey ; //默认的合并请求键private f 工nal String defaultThreadPoolKey ; //默认的线程池键private final Executiontype executiontype ; I I 执行类型}
在HystrixCommandFactory 类中,用于创建HystrixCommand 的方法如下所示:
//HystrixCommandFactory . javapublic Hystrxinvokable create(MetaHolder metaHolder) { HystriX invokable executable ;//构建请求合并的命令if (metaHolder . isCollapserAnnotationPresent () ) (executable = new CommandCollapser(metaHolder) ;} else if (metaHolder isObservable()) (executable = 口ew GenericObservableCommand (HystrixCommandBui lderFactory .getinstance() create(metaHolder)) ; else (executable = new GenericCommand(Hystrix CommandBu lderFactory . getinstance() .create (metaHolder)) ;return executable;}
根据MetaHolder# isObservable 方法返回属性的不同, 将会构建不同的命令,比如HystrixCommand 或者HystrixObservableCommand ,前者将同步或者异步执行命令, 后者异步回调执行命令。Hystrix 根据被包装方法的返回值来决定命令的执行方式
根据被包装方法的返回值类型决定命令执行的Execution Type ,从而决定构建HystrixCommand 还是HystrixObservableCommand 。其中Future 类型的返回值将会被异步执行, rx 类型的返回值将会被异步回调执行,其他的类型将会被同步执行。
CommandExecutor 根据MetaHolder 中ExecutionType 执行类型的不同,选择同步执行、异步执行还是异步回调执行,返回不同的执行结果。同步执行,直接返回结果对象;异步执行,返回Future ,封装了异步操作的结果;异步回调执行将返回Observable ,封装响应式
执行的结果,可以通过它对执行结果进行订阅,在执行结束后进行特定的操作。
虽然类图很复杂,但是最终实现类只有三个,分别是同步或异步执行命令的GenericCommand ; 请求合并执行命令的BatchHystrixCommand , 以及异步回调执行命令的GenericObservableCommand
在observe 方法中, 首先将创建一个方法ReplaySu均ect, rx 中的Subject 既是一个Observable 也是一个Observer 。接着调用toObservable 方法获取到懒执行的Observable,通过创建的ReplaySubject 订阅该Observable ,启动Observable 中相关命令, 同时返回ReplaySubject 给后续的观察者,用于订阅来获取执行结果( ReplaySubject 会推送所有来自原始Observable 的事件给观察者,无论它们是何时订阅的) 。
AbstractCommand#toObservable
1 ) 首先通过Observable#defer 方法来构建返回的Observable a 以Observable#defer 方式声明的Observable 只有当有观察者订阅才会真正开始创建,并且是为每一个观察者创建一个新的Observable ,这就保证了toObservable 方法返回的Observable 是纯净的,并没有
开始执行命令。
2 )在构建Observable 过程中,先通过commandState 查看当前的命令执行状态,保证命令未开始执行并且每条命令只能执行一次。
3 )如果允许请求缓存并且缓存存在的话,将尝试从缓存中获取对应的执行结果,并直接返回结果。
4 )如果无法获取缓存,通过applyHystrixSemantics 方法构建用于返回的Observable 。
5 )如果允许请求缓存,将ObsErvable 放置到缓存中用于下一次调用。
6 ) 最后为返回Observable 添加提前定义好的回调方法。
在上述的流程中,需要重点关注两个地方,一个是HystrixRequestCache ,其内封装了
缓存Observable 的逻辑;另一个是applyHystrix Semantics 回调方法,其内封装了断路、资源隔离等核心断路器逻辑。
·HystrixRequestCache 请求援存
HystrixRequestCache 对Observable 进行缓存操作,使用每个命令特有的cacheKey 对Observable 进行缓存,通过ConcurrentHashMap 保存缓存结果以保证线程安全。
HystrixRequestCache 中缓存的并不是直接的Observable , 而是被封装好的HystrixCachedObservable。在HystrixCachedObservable 中,通过ReplaySubject 订阅需要缓存的Observable ,保证了缓存的Observable 能够多次执行.
applyHystrixSemantics 断路器判断与获取信号量
在applyHystrixSemantics 回调方法中, 通过AbstractCommand#app ly HystrixSemantics方法声明Observable 。它主要工作是判断断路器是否打开, 以及尝试获取信号量用于执行命令(仅在信号量隔离模式下生效)
在AbstractColilIIland#applyHystrix.Semant ic s 中, 首先通过断路器Hystrix.CircuitBreaker 检查链路中的断路器是否开启, 如果开启的话,执行断路失败逻辑handleShortCircuitViaFallback方法。如果通过断路器的检查, 将会尝试获取信号量。如果不能获取信号量,那么执行信号量获取失败逻辑handleSemaphoreRejection ViaFallback 方法。当上述检查都通过了,才执行exec uteCornmandAndObserve 方法获取执行命令的Observable , 并为该Observable 配置
回调操作, 该回调操作在命令执行结束后以及取消订阅时用于释放信号量。
executeCommandAndObserve 配置执行异常回调方法
executeCommandAndObserve 方法主要用于为执行命令Observable 配置执行失败的回调方法,对执行失败的结果进行记录和处理。
executeCo mm an dWith Specifiedlsolation 配置线程隔离和超时控制
executeCommandW ithSpeci fiedlsolatio n 方法为命令构造了隔离的执行环境,提供两种资源隔离的方式, 线程隔离和信号量隔离;如果Hystrix 配置中开启了超时控制,还会通过Observable#lift 方法将现有的Observable 转化为添加了超时检查的Observable 。
getExecutionObservable 配置被封装的远程调用方法
getUserEx巳cutionObservable 方法将为命令获取在声明HystrixCommand 时被包装的具
体远程调用方法。在getUserExec utionObservable 方法中,通过getExecutionObservable 抽象方法将具体实现延迟到子类中
到此,相信大家对“如何理解SpringCloud Hystrix源码解析”有了更深的了解,不妨来实际操作一番吧!这里是创新互联网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!