• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

Hystrix熔断器-源码

武飞扬头像
汪爪蛙
帮助1

Hystrix熔断器的使用,在启动类上添加注解@EnableCircuitBreaker,然后在具体的请求上添加@HystrixCommand,则对该接口的调用会使用熔断的规则。我们以@EnableCircuitBreaker注解为入口,分析熔断器的源码。

学新通

注解中引入了一个类EnableCircuitBreakerImportSelector,进入该类查看具体情况。学新通

该类继承了SpringFactoryImportSelector,这个是用来加载spring.factory里面的配置类的。进入SpringFactoryImportSelector查看都加载了哪些类。

学新通

由此可只,会加载spring.factory里面的以EnableCircuitBreaker全限定类名为key的所有Bean。接下来就看看spring.factory里面都装配了哪些。

学新通

装配了HystrixCircuitBreakerConfiguration,进入类中,查看类中具体都做了哪些事情。

学新通

这里面装配一个切面,初步猜测hytrix熔断器是通过切面给方法进行增强来实现的熔断和服务降级的操作。 

学新通

在此可看到,切面是对HystrixCommand和HystrixCollapser为切入点,进行了环绕增强。里面的内容主要包括,根据方法的配置创建了HystrixInvokable,该接口在该处的主要实现为GenericCommand,实现类中封装了对调用方法的执行,以及对降级回退方法的执行。最终通过CommandExecutor#execute执行方法获取结果。

上面我们介绍了hytriy通过Aop切面对方法进行增强来控制请求时候得限流和熔断以及调用回调方法。我们继续跟进到具体得方法调用当中。

学新通

这里主要调用的方法为toObservable()方法,后面就是获取请求结果。toObservable方法中采用了RxJava的方式写了调用逻辑。RxJava其实就相当于发布订阅模式或者是观察者模式,可以通过这个文章来了解一下RxJava(我所理解的RxJava——上手其实很简单(一) - 简书 (jianshu.com))

学新通 这个方法的前大半部分都是定义了一下执行逻辑,而最后的reture之后才是真正的发布事件并且执行逻辑的地方。这里面的大致的意思是执行调用,如果开启了hytriy的请求缓存则会将请求结果缓存并且请求的时候缓存命中则直接从缓存中获取数据。第一个红框中是没有开启请求缓存或者是缓存未命中的时候,则会defer发布一个事件。了解了RaJava的同学应该会知道,发布者使用refer方法发布一个事件之后只有当有订阅者的时候才会真正的创建发布者。我们这里先看一下发布的内容。

学新通 这里面的逻辑就是调用具体的方法

学新通 方法内的具体内容为上图所示,显示旁段熔断器是否熔断,是否允许请求通过,如果不允许则直接调用fallBack方法,如果运行则进行红框中的调用逻辑。

那么hytriy是如何去控制请求的熔断以及熔断之后进行滑动窗口的逻辑的呢。回到toObservable()方法中,最后一行,最终还会执行terminateCommandCleanup中的逻辑,我们进入这个方法,查看具体的作用。跟踪代码我们进入到HystrixThreadEventStream中的方法

学新通 HystrixThreadEventStream 是hystrix的事件汇总的类。这个方法中通writeOnlyCollapserSubject发布了这次的执行结果事件。事件发布之后,然后就会有监听者进行监听,而HealthCountsStream则是事件的监听者。

学新通

构造方法中会订阅这个 HystrixThreadEventStream并且计算滑动窗口,我们看一下具体的滑动窗口的逻辑。

学新通

这里并是具体的滑动窗口的逻辑。

  1.  
    this.sourceStream = this.bucketedStream
  2.  
    .window(5, TimeUnit.SECONDS) // 5秒作为一个基本块
  3.  
    .flatMap(INNER_BUCKET_SUM) // 基本块内数据求和
  4.  
    .window(numBuckets, 1) // numBuckets个块作为一个窗口,滚动布数为1
  5.  
    .flatMap(reduceWindowToSummary) // 窗口数据求和
  6.  
    .doOnSubscribe(new Action0() {
  7.  
    public void call() {
  8.  
    // 订阅者逻辑
  9.  
    BucketedRollingCounterStream.this.isSourceCurrentlySubscribed.set(true);
  10.  
    }
  11.  
    })

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgccbcj
系列文章
更多 icon
同类精品
更多 icon
继续加载