SpringCloud熔断器之Hystrix源剖析

前面我们已经看过了springcloud的注册中心eureka、负载均衡ribbon的源码,本文我们继续看一下springcloud的断路器Hystrix的源码

源码入口

 进入org.springframework.cloud.netflix.hystrix.EnableHystrix

 进入org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker

 可以看到这里就是引入了一个断路器选择器org.springframework.cloud.client.circuitbreaker.EnableCircuitBreakerImportSelector进入里面

 可以看到这里就只有一个判断是否启用的方法,我们点进父类org.springframework.cloud.commons.util.SpringFactoryImportSelector中去看看里面做了啥

  我们可以看到,在这个里的构造器中初始化了注解的类型,而从上一张图片我们可以知道这个泛型是org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker

在org.springframework.cloud.commons.util.SpringFactoryImportSelector类中,我们看到有一个org.springframework.cloud.commons.util.SpringFactoryImportSelector#selectImports方法,我们看一下这里面都做些啥

 可以看到,这里主要就是获取注解的配置属性以及加载自动装载bean的factory,我们继续跟进加载factory的方法

进入org.springframework.core.io.support.SpringFactoriesLoader#loadFactoryNames

 

可以看到这里主要就是从缓存中获取一下factory,如果没有找到就去指定目录加载,然后放入缓存。接下来我们看一下这个目录中都放了存了什么 

 进入org.springframework.cloud.netflix.hystrix.HystrixCircuitBreakerConfiguration

 

 发现com.netflix.hystrix.contrib.javanica.aop.aspectj.HystrixCommandAspect这个好像有点有点像@HystrixCommand注解哦,咱们点进去看看

 嗯?看起来着几个注解好像都是aop的啊,作者的注释也是说是这个是用来处理HystrixCommand注解标记的方法的切面。

接下来我们就一起来看看这个切面环绕通知里都做了什么

 可以看到这个方法里主要做了四件事

1、通过通过joinpoint获取原始方法;

2、通过joinpoint封装方法元信息;

3、获取Hystrix可调用对象;

4、将可调用对象委派出去;

下面我们就重点来关注一下获取可调用对象

进入com.netflix.hystrix.contrib.javanica.command.HystrixCommandFactory#create

进入com.netflix.hystrix.contrib.javanica.command.GenericCommand

可以看到,这里有调用了父类的构造方法,而且自己重写了父类的run方法和getFallBack方法,我们接下来看一下它的继承体系图

 

 可以看到他继承了好几个类,继续跟进父类com.netflix.hystrix.contrib.javanica.command.AbstractHystrixCommand

 继续跟进com.netflix.hystrix.HystrixCommand#HystrixCommand(com.netflix.hystrix.HystrixCommand.Setter)

 继续跟进

 继续跟进com.netflix.hystrix.AbstractCommand#AbstractCommand

 哦,原来这里做了一些初始化动作,这里面有一些熟悉的字眼,线程池?熟悉Hystrix的同学应该都知道,他可以每个方法使用一个线程池,这里的初始化时怎么初始化的呢,咱们点进去看看

 

 进入com.netflix.hystrix.HystrixThreadPool.Factory#getInstance

 

 可以看到,这里就是先从currentHashMap中获取,如果没有再创建一个新的线程池放到map中

继续跟进com.netflix.hystrix.HystrixThreadPool.HystrixThreadPoolDefault#HystrixThreadPoolDefault

 可以看到这里通过策略模式获取线程池

继续跟进com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategy#getThreadPool

 可一个看到这里创建的是jdk原生线程池

从上面这些父类构造器中我们可以知道,其实他就是在父类初始化一些必要参数。

接下来我们回到com.netflix.hystrix.contrib.javanica.aop.aspectj.HystrixCommandAspect#methodsAnnotatedWithHystrixCommand中看看最终是怎么执行的

进入 com.netflix.hystrix.contrib.javanica.command.CommandExecutor#execute

 

 继续跟进

 进入com.netflix.hystrix.HystrixExecutable

 再进入就是RxJava的内容了,咱们就不继续跟进了

原文地址:https://www.cnblogs.com/qsky/p/13857932.html