Hystrix-短路器原理及实战

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Anbang713/article/details/85837801

短路器是什么?顾名思义,短路器的作用是用来阻断的。即当打开短路器时,后续对command的执行会直接执行fallback降级。那么什么情况下短路器会被打开呢?下面我们一起了解下这其中的原理。

一、短路器的工作原理

1、短路器打开的前提是经过短路器的流量超过了一定的阈值。比如说在10s内,经过短路器的流量必须达到20个才会判断要不要短路。

2、到达短路器的流量异常占比必须超过一定的阈值。比如我们说在10s,经过短路器的流量达到了30个,同事其中异常的访问数量,占到了一定的比例,比如说50%的请求都是异常的,那就开启短路。

3、短路器达到了一定的阈值,且异常占比也达到了阈值,那么此时短路器就会从close状态转换到open状态。

4、短路器打开的时候,所有经过该短路器的请求全部被短路,不调用后端服务,直接fallback降级。

5、经过一段时间之后,短路器会处于半开状态,让一条请求经过短路器,看能否正常调用,如果调用成功,那么短路器就会自动关闭。

二、短路器相关配置

1、circuitBreaker.enabled:控制短路器是否允许工作,包括跟踪依赖服务调用的健康状况,以及对异常情况过多时是否允许触发短路,默认是true。HystrixCommandProperties.Setter().withCircuitBreakerEnabled(boolean value)

2、circuitBreaker.requestVolumeThreshold:设置一个rolling window,滑动窗口中,最少要有多少个请求时才触发开启短路。(如果设置为20(默认值),那么在一个10秒的滑动窗口内,如果只有19个请求,即使这19个请求都是异常的,也是不会触发开启短路器的。)HystrixCommandProperties.Setter().withCircuitBreakerRequestVolumeThreshold(int value)

3、circuitBreaker.sleepWindowInMilliseconds:设置在短路之后,需要在多长时间内直接reject请求,然后在这段时间之后,再重新到holf-open状态,尝试允许请求通过以及自动恢复,默认值是5000毫秒。HystrixCommandProperties.Setter().withCircuitBreakerSleepWindowInMilliseconds(int value)

4、circuitBreaker.errorThresholdPercentage:设置异常请求量的百分比,当异常请求达到这个百分比时,就触发打开短路器,默认是50,也就是50%。HystrixCommandProperties.Setter().withCircuitBreakerErrorThresholdPercentage(int value)

5、circuitBreaker.forceOpen:如果设置为true的话,直接强迫打开短路器,相当于是手动短路了,手动降级,默认false。HystrixCommandProperties.Setter().withCircuitBreakerForceOpen(boolean value)

6、circuitBreaker.forceClosed:如果设置为ture的话,直接强迫关闭短路器,相当于是手动停止短路了,手动升级,默认false。HystrixCommandProperties.Setter().withCircuitBreakerForceClosed(boolean value)

三、实战

3.1、创建command

public class CommandCircuitBreaker extends HystrixCommand<String> {
  private String tag;

  public CommandCircuitBreaker(String tag) {
    super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("CommandCircuitBreakerGroupKey"))
        .andCommandPropertiesDefaults(HystrixCommandProperties.Setter()//
            .withCircuitBreakerRequestVolumeThreshold(30)// 设置短路器的流量必须到达30
            .withCircuitBreakerErrorThresholdPercentage(40)// 异常占比达到40%
            .withCircuitBreakerSleepWindowInMilliseconds(3000)));// 滑动窗口3s,3s后处于半开状态
    this.tag = tag;
  }

  @Override
  protected String run() throws Exception {
    if ("error".equals(tag)) {
      throw new Exception("抛出异常");
    }
    return "-----------------成功-----------------";
  }

  @Override
  protected String getFallback() {
    return "-----------------降级处理-----------------";
  }

}

3.2、执行command

public class CommandCircuitBreakerTest {

  public static void main(String[] args) throws Exception {

    for (int i = 0; i < 15; i++) {
      CommandCircuitBreaker breaker = new CommandCircuitBreaker("success");
      System.out.println("第" + (i + 1) + "次请求,结果为:" + breaker.execute());
    }
    for (int i = 0; i < 25; i++) {
      CommandCircuitBreaker breaker = new CommandCircuitBreaker("error");
      System.out.println("第" + (i + 1) + "次请求,结果为:" + breaker.execute());
    }
    // 因为时间窗口统计异常占比需要时间,所以这里等待了2s后
    Thread.sleep(2000);

    for (int i = 0; i < 10; i++) {
      CommandCircuitBreaker breaker = new CommandCircuitBreaker("success");
      System.out.println("第" + (i + 1) + "次请求,结果为:" + breaker.execute());
    }
    // 统计单位,有一个时间窗口的,我们必须要等到那个时间窗口过了以后,才会说,hystrix看一下最近的这个时间窗口
    // 比如说,最近的10秒内,有多少条数据,其中异常的数据有没有到一定的比例
    // 如果到了一定的比例,那么才会去短路
    System.out.println("尝试等待3秒钟。。。。。。");
    Thread.sleep(3000);
    for (int i = 0; i < 10; i++) {
      CommandCircuitBreaker breaker = new CommandCircuitBreaker("success");
      System.out.println("第" + (i + 1) + "次请求,结果为:" + breaker.execute());
    }
  }
}

3.3、执行结果

(1)成功执行15次之后,开始抛出异常

(2)后面25次都是异常请求,然后等待2s,让短路器进行异常占比统计。再发起正常的请求,此时直接走了fallback降级处理,我们再等待3s,让短路器处于半开状态,发起正常请求,此时执行成功。

猜你喜欢

转载自blog.csdn.net/Anbang713/article/details/85837801
今日推荐