zoukankan      html  css  js  c++  java
  • 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的内容了,咱们就不继续跟进了

  • 相关阅读:
    习题10-2 递归求阶乘和(15 分)
    在过滤器中得到模型状态信息
    理解OAuth 2.0
    asp.net mvc 控制器的依赖注入(使用Ninject)
    web.routing 学习
    深度优先和广度优先的基础应用
    数的全排
    C# 表达式树
    C#中RSA的简单使用
    select into 和insert into select
  • 原文地址:https://www.cnblogs.com/qsky/p/13857932.html
Copyright © 2011-2022 走看看