Spring Cloud Hystrix 源码分析04 Metrics 收集 && 熔断实现

Spring Cloud Hystrix 源码分析04 Metrics 收集 && 熔断实现

Spring Cloud Hystrix 源码分析04 Metrics 收集 && 熔断实现

1. rxjava
1.2 Observable.share
Observable.share()属于连接操作,组合操作。

Observable.publish( ),将一个Observable转换为一个ConnectableObservable(可连接的Observable)
ConnectableObservable.refCount( ),让一个ConnectableObservable表现得像一个普通的Observable
ConnectableObservable与普通的Observable差不多,除了这一点:ConnectableObservable在被订阅时并不开始发射数据,只有在它的connect()被调用时才开始。用这种方法,你可以等所有的潜在订阅者都订阅了这个Observable之后才开始发射数据。

1.3 Subject
Hystrix 基于 RxJava,本文涉及到 Subject 概念,这里提一下 rx.subjects.Subject。Subject 继承Observable,因此可作为被观察者、数据源,也就是一个数据发射器;实现了接口 Observer,因此可作为观察者,可以订阅其他Observable,处理Observable发射出的数据。因此,Subject既可以发射数据,也可以接收数据。

2. Metrics 收集流程
    2.1 HystrixCommandMetrics
每个Command的构造器中会获取一个HystrixCommandMetrics工具,用来记录metrics,也就是说,每个CommandKey会拥有一个对应的HystrixCommandMetrics工具。下面是利用HystrixCommandMetrics工具发射 各种 的事件。
Spring Cloud Hystrix 源码分析04 Metrics 收集 && 熔断实现

2.2 HystrixThreadEventStream
HystrixCommandMetrics主要是通过HystrixThreadEventStream工作的!

那HystrixThreadEventStream是什么呢?

每个线程拥有自己的HystrixThreadEventStream(从ThreadLocal中获取对象),它包含了很多Subject<事件,事件>,用来接收和发射数据。

2.3 HystrixEventStream
上面讲过HystrixThreadEventStream构建事件并转发事件,HystrixCommandCompletionStream就是专门用于接受并处理各种事件(HystrixCommandEvent)的,准确的讲是承上启下,它属于 HystrixEventStream 的一种。它有几个子类:

HystrixCommandCompletionStream
HystrixCommandStartStream
HystrixThreadPoolCompletionStream
HystrixThreadPoolStartStream
HystrixCollapserEventStream
接着上面源码继续分析HystrixCommandCompletionStream,可以接收数据,并将数据提供给其他消费者。上面提的那个问题HystrixCommandCompletionStream的接盘侠是BucketedCounterStream

2.4 HystrixPlugins

您可以通过实现插件来修改Hystrix的行为,或者向其添加其他行为。您可以通过 HystrixPlugins 注册这些插件

2.5 HystrixEventNotifier

在执行 HystrixCommand和 HystrixObservableCommand期间发生的事件在 HystrixEventNotifier上触发,以提供警报和统计信息收集的机会

2.6 HystrixMetricsPublisher
每一个metrics实例将被捕捉,同时请求 HystrixMetricsPublisher 的实现类并初始化它,这使实现类有机会接收metrics数据对象,并启动一个后台进程来处理metrics,默认实现类不会在任何地方发布它们
2.8 HystrixCommandExecutionHook
一个HystrixCommandExecutionHook实现使您能够访问 HystrixInvokable(Hystrixcommand或 Hystrixobserveblecommand)的执行生命周期,这样您就可以注入行为、日志记录、重写响应、更改线程状态等
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Spring Cloud Hystrix 源码系列:熔断器

circuit-breaker, circuit表示电路,译为熔断器非常精准,而Hystrix属于自动恢复的智能熔断器,它保护的着你的系统,宿主在调用方的应用系统中,避免因为依赖系统的异常或宕机而引发一系列连锁反应。Hystrix 原理也比较简单,在一个时间窗口下,通过不断收集依赖服务(第三方)请求指标信息(sucess、failure、timeout、rejection),当达到设定熔断条件时(默认是请求失败率达到50%)则进行熔断
Spring Cloud Hystrix 源码分析04 Metrics 收集 && 熔断实现

1.1 桶

假定以秒为单位来统计请求处理情况,上面每个格子代表1秒,格子中的数据就是1秒内各处理结果的请求数量,格子称为 Bucket(译为桶)

1.2 滑动窗口

若每次的决策都以10个Bucket的数据为依据,计算10个Bucket的请求处理情况,当失败率超过50%时就熔断。10个Bucket就是10秒,这个10秒就是一个 滑动窗口(Rolling window)。滑动意味着:在没有熔断时,每当收集好一个新的Bucket后,就会丢弃掉最旧的一个Bucket(深色的 [ 23 5 2 0 ] )就是被丢弃的桶)。

1.3 官方完整的流程图

策略是:不断收集数据,达到条件就熔断;熔断后拒绝所有请求一段时间(sleepWindow);然后放一个请求过去,如果请求成功,则关闭熔断器,否则继续打开熔断器。
Spring Cloud Hystrix 源码分析04 Metrics 收集 && 熔断实现

1.4 断路器打开意味着什么

断路器处于 OPEN 状态时,链路处于非健康状态,命令执行时,直接调用回退逻辑,跳过正常逻辑。

核心实现 HystrixCircuitBreaker

Spring Cloud Hystrix 源码分析04 Metrics 收集 && 熔断实现

1.markSuccess方法 : 关闭熔断器,并且reset metrics

Spring Cloud Hystrix 源码分析04 Metrics 收集 && 熔断实现

2.allowRequest:

    2.1 判断熔断器打开,则不允许请求

   2.2. 心跳健康检查,小于配置的阈值,则允许请求执行 (根据metrics.getHealthCounts判断是否可以打开熔断器)

         HealthCounts很关键,它是滚动窗口的请求统计信息    

Spring Cloud Hystrix 源码分析04 Metrics 收集 && 熔断实现

3.5 关于CLOSED & OPEN &HALF_OPEN
    在最新Hystrix 1.5.18版本已经移除了Status,在HystrixCircuitBreakerImpl已经可以看出,采用circuitOpen(bool型) 代替status(CLOSED 、OPEN 、HALF_OPEN),这样的好处是对调用者而言熔断器API更简单。

   HALF_OPEN是如何实现的?

实现逻辑也比较简单,通过allowRequest方法(每个command执行execute前必须调用,之前讲过的)中调用allowSingleTest方法,而allowSingleTest实现了半开。当断路器打开时,记录当前时间到circuitOpenedOrLastTestedTime,这时有新请求时,会判断当前时间是否大于circuitOpenedOrLastTestedTime加sleepWindowInMilliseconds,如果是返回true(代表请求通过),更新circuitOpenedOrLastTestedTime为最新的时间。当然如果用户任务执行成功的话,通过markSuccess关闭熔断器!