Hystrix 的熔断

熔断断路器的重要功能之一,是实现快速失败的基础;

Hystrix的熔断器设计成一个接口  com.netflix.hystrix.HystrixCircuitBreaker,解释如下:

/**
 * Circuit-breaker logic that is hooked into {@link HystrixCommand} execution and will stop allowing executions if failures have gone past the defined threshold.
 * <p>
 * It will then allow single retries after a defined sleepWindow until the execution succeeds at which point it will again close the circuit and allow executions again.
 */

大意就是,在失败请求达到一定量时终止执行HystrixCommand,并且允许一定时间(sleepWindow)后重试一次,成功后就关掉断路器;

熔断主要涉及到三个方面的问题:

  1、如何实现熔断,如何恢复

  2、怎么判断是否该熔断

  3、判断熔断的基础指标数据如何收集和统计

上面就已经大致解释了第一个问题;

下面就主要围绕这三个问题进行解释。

一、如何熔断

  断路器中熔断与恢复一般设计成一个开关,使用一个布尔值来实现

/* track whether this circuit is open/closed at any given point in time (default to false==closed) */
private AtomicBoolean circuitOpen = new AtomicBoolean(false);

   当请求失败达到熔断阈值(threshold)时,断路器就会打开,请求就会快速失败;

  当断路器打开一段时间后(sleepWindow)后,组件会使用一个请求去重试,看看链路是否恢复,如果恢复就关闭断路器,接下来的请求就会发送到依赖的服务上;

二、怎么判断是否该熔断

  Hystrix 在一个滑动窗口时间内,统计出各种状态的请求数量和比例(failure + success + timeout + threadPoolRejected + semaphoreRejected), 就是下面的HealthCounts;

            HealthCounts health = metrics.getHealthCounts();
            if (health.getTotalRequests() < properties.circuitBreakerRequestVolumeThreshold().get()) {        
                return false;
            }

            if (health.getErrorPercentage() < properties.circuitBreakerErrorThresholdPercentage().get()) {
                return false;
            } else {
                // our failure rate is too high, trip the circuit
                if (circuitOpen.compareAndSet(false, true)) {circuitOpenedOrLastTestedTime.set(System.currentTimeMillis());
                    return true;
                } else {
                    return true;
                }
            }

  判断是否打开有两种方式:一种是设置一个阈值,一种是设置一个失败比例;

三、如何收集和统计指标数据

  由第二部分内容我们知道HealthCounts 的数据来源于metrics(指标),那么指标是如何收集和统计的呢?

  熔断统计就会涉及到两个基本信息:总共统计数据和单位时间(rolling window)统计数据;注:rolling window is defined by HystrixCommandProperties#metricsRollingStatisticalWindowInMilliseconds()

  收集时将hystrix的命令调用抽象了事件流,利用响应式编程技术将事件汇总;

  统计时使用RxJava的window/reduce/flatmap等命令将单位事件内的数据进行汇总存储(桶),再将桶内的数据按成功/失败的进行统计;

  统计的数据就是metrics(指标)数据;

 

  网上看到一片写得不错的文章:

  https://www.sczyh30.com/posts/%E9%AB%98%E5%8F%AF%E7%94%A8%E6%9E%B6%E6%9E%84/netflix-hystrix-1-5-sliding-window/

  并附上该作者画的总体流程图:

  

 

 

  

posted @ 2019-09-11 21:54  lion_eagle  阅读(615)  评论(0编辑  收藏  举报