• 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的内容了,咱们就不继续跟进了

  • 相关阅读:
    python 操作ie 登陆土豆再退出
    python之sqlite3使用详解(转)
    python 获取当前目录下文件(转)
    python中使用time模块计算代码执行效率的精度测试(转)
    pythonhttplib模块使用(转)
    python技巧31[python中使用enum](转)
    python怎样压缩和解压缩ZIP文件(转)
    httplib2python下的http请求终结者(转)
    Python:使用ctypes库调用外部DLL(转)
    整理了下控制ie的代码(转)
  • 原文地址:https://www.cnblogs.com/qsky/p/13857932.html
Copyright © 2020-2023  润新知