resilience4j之CircuitBreaker熔断器——CircuitBreakerConfig 配置

一. 为什么要有断路器

当A服务调用B服务,由于网络原因或自身原因出现问题时,A就会等待B的相应,当有更多的服务器请求资源时,就会有更多的请求A等待B的响应,这样就会发生连锁效应(雪崩效应),因为服务A有太多的线程导致服务A线程耗尽从而导致A也无法接受请求出现问题,断路器就是解决这一问题的

二. 什么是断路器

断路器有三种正常状态:完全打开OPEN,半开HALF_OPEN,关闭CLOSED,还有两种通过设置的强制状态:强制不可用DISABLED,强制打开FORCED_OPEN。

三:滑动窗口的类型

  1. 基于计数的滑动窗口(默认,CircuitBreakerConfig可看出)
  2. 基于时间的滑动窗口
    public enum SlidingWindowType {
        TIME_BASED, COUNT_BASED
    }

四:CircuitBreakerConfig配置

  1. CircuitBreakerConfig 类定义了相关配置与属性,主要有如下:
    //请求调用失败的阈值,百分比。默认是50%,即服务A调用服务B,此时B调用失败即算作一个失败调用
    public static final int DEFAULT_FAILURE_RATE_THRESHOLD = 50; // Percentage
    //慢调用的阈值,百分比
    public static final int DEFAULT_SLOW_CALL_RATE_THRESHOLD = 100; // Percentage
    // 熔断器在打开状态时的持续时间。默认是60秒
    public static final int DEFAULT_WAIT_DURATION_IN_OPEN_STATE = 60; // Seconds
    // 熔断器在半开状态下的ring buffer大小。默认10,不超过此值就可以通过请求
    public static final int DEFAULT_PERMITTED_CALLS_IN_HALF_OPEN_STATE = 10;
    // 熔断器在关闭状态下的可以计算失败率的最小值,默认100
    public static final int DEFAULT_MINIMUM_NUMBER_OF_CALLS = 100;
    //滑动窗口大小,熔断器在关闭状态下的ring buffer大小
    public static final int DEFAULT_SLIDING_WINDOW_SIZE = 100;
    //慢调用的时间,即当服务A调用服务B时,B的执行时间超过了60秒就算作是慢调用
    public static final int DEFAULT_SLOW_CALL_DURATION_THRESHOLD = 60; // Seconds
    //滑动窗口类型,默认为基于计数的 COUNT_BASED
    public static final SlidingWindowType DEFAULT_SLIDING_WINDOW_TYPE = SlidingWindowType.COUNT_BASED;
    public static final boolean DEFAULT_WRITABLE_STACK_TRACE_ENABLED = true;
    // 是否记录请求调用失败的断言,默认所有异常都记录
    private static final Predicate<Throwable> DEFAULT_RECORD_EXCEPTION_PREDICATE = throwable -> true;
    //忽略异常
    private static final Predicate<Throwable> DEFAULT_IGNORE_EXCEPTION_PREDICATE = throwable -> false;
    // The default exception predicate counts all exceptions as failures.
    private Predicate<Throwable> recordExceptionPredicate = DEFAULT_RECORD_EXCEPTION_PREDICATE;
    // The default exception predicate ignores no exceptions.
    private Predicate<Throwable> ignoreExceptionPredicate = DEFAULT_IGNORE_EXCEPTION_PREDICATE;

    // 默认为false,是否自动从打开到半开,当waitDurationInOpenState时间一过,是否自动从OPEN切换到HALF_OPEN
    // true:waitDurationInOpenState到期后open自动变为half_open
    //false,得等到再有请求后状态才会变为half_open,否则即使waitDurationInOpenState到期状态依然是open    
    private boolean automaticTransitionFromOpenToHalfOpenEnabled = false;

  1. CircuitBreakerConfig 利用Builder模式 创建了CircuitBreakerConfig实例,并提供动态设置属性的方法
/**
     * 构造者模式
     */
 public static class Builder {

        @Nullable
        private Predicate<Throwable> recordExceptionPredicate;
        @Nullable
        private Predicate<Throwable> ignoreExceptionPredicate;

        // 请求调用失败,存储异常记录的集合
        @SuppressWarnings("unchecked")
        private Class<? extends Throwable>[] recordExceptions = new Class[0];
        // 请求调用失败,忽略异常记录的集合
        @SuppressWarnings("unchecked")
        private Class<? extends Throwable>[] ignoreExceptions = new Class[0];
		。。。
		//创建实例并设置属性
        public Builder(CircuitBreakerConfig baseConfig) {
            this.waitIntervalFunctionInOpenState = baseConfig.waitIntervalFunctionInOpenState;
            。。。
            this.writableStackTraceEnabled = baseConfig.writableStackTraceEnabled;
        }

		//动态设置调用失败阈值
        public Builder slidingWindow(int slidingWindowSize, int minimumNumberOfCalls,
            SlidingWindowType slidingWindowType) {
			.。。。 
            if (slidingWindowType == SlidingWindowType.COUNT_BASED) {
                //如果是基于计数的滑动窗口,minimumNumberOfCalls取两者最小值
                this.minimumNumberOfCalls = Math.min(minimumNumberOfCalls, slidingWindowSize);
            } else {
               //基于时间
                this.minimumNumberOfCalls = minimumNumberOfCalls;
            }
        }
}
  1. CircuitBreakerConfig提供了两种获取Builder对象的方法:使用默认配置和自定义配置
    /**
     * Returns a builder to create a custom CircuitBreakerConfig.
     * 1.使用默认配置创建Builder对象,得到builder对象就可以根据builder提供的方法改变配置
     * @return a {@link Builder}
     */
    public static Builder custom() {
        return new Builder();
    }

    /**
     * Returns a builder to create a custom CircuitBreakerConfig based on another
     * CircuitBreakerConfig.
     *  2.使用传入的自定义的配置baseConfig的builder对象,得到builder对象就可以根据builder提供的方法改变配置
     * @return a {@link Builder}
     */
    public static Builder from(CircuitBreakerConfig baseConfig) {
        return new Builder(baseConfig);
    }
  1. CircuitBreakerConfig还提供了获取配置的方法,如获取滑动窗口的类型:
    public SlidingWindowType getSlidingWindowType() {
        return slidingWindowType;
    }

综上: 该类为创建CircuitBreakerConfig实例,设置并获取CircuitBreaker配置

yml文件配置参考

resilience4j.circuitbreaker:
  configs:
    default: # @CircuitBreaker的name
      registerHealthIndicator: true  #健康监测
      ringBufferSizeInClosedState: 2 # 熔断器关闭时的缓冲区大小,不会限制线程的并发量,在熔断器发生状态转换前所有请求都会调用后端服务(缓冲区满时才会计算失败率)
      ringBufferSizeInHalfOpenState: 1 # 熔断器半开时的缓冲区大小,会限制线程的并发量(只允许ringBufferSizeInHalfOpenState个并发),
                                      # 例如缓冲区为10则每次只会允许10个请求调用后端服务
                                      # 之所以能限制并发,CircuitBreakerStateMachine使用了AtomicInteger:this.permittedNumberOfCalls = new AtomicInteger(permittedNumberOfCallsInHalfOpenState);

      waitDurationInOpenState: 10s # 熔断器从打开到半开需要的时间
      failureRateThreshold: 50 # 熔断器打开的失败阈值或半开状态使用的同一个失败率阈值
      slowCallDurationThreshold: 600s # 慢调用的时间,单位s
      slowCallRateThreshold: 100 # 慢调用的比例阈值
      eventConsumerBufferSize: 7 # 事件缓冲区大小???
      minimumNumberOfCalls: 4  #默认100
#      slideWindowType: COUNT_BASED # 配置滑动窗口的类型,默认为count_based
#      automaticTransitionFromOpenToHalfOpenEnabled: false # 默认为false,是否自动从打开到半开,当waitDurationInOpenState时间一过,是否自动从OPEN切换到HALF_OPEN
#                                                      # true:waitDurationInOpenState到期后open自动变为half_open,
#                                                      #如果为false,得等到再有请求后状态才会变为half_open,否则即使waitDurationInOpenState到期状态依然是open
      recordExceptions: # 记录的异常
        - org.springframework.web.client.HttpServerErrorException
        - java.io.IOException
        - java.util.concurrent.TimeoutException
        - org.springframework.web.client.ResourceAccessException
        - org.springframework.web.client.HttpClientErrorException
      ignoreExceptions: # 忽略的异常
      recordFailurePredicate:  #用于判断哪些异常应该算作失败纳入断路器统计,默认是Throwable类型

五:CircuitBreakerProperties读取配置

CircuitBreakerProperties 作为读取yml或properties文件中以"resilience4j.circuitbreaker"开头的配置

@ConfigurationProperties(prefix = "resilience4j.circuitbreaker")
public class CircuitBreakerProperties extends CircuitBreakerConfigurationProperties {

}

定义了CircuitBreaker切入顺序

public class CircuitBreakerConfigurationProperties extends
    io.github.resilience4j.common.circuitbreaker.configuration.CircuitBreakerConfigurationProperties {

    //  倒第二
    private int circuitBreakerAspectOrder = Ordered.LOWEST_PRECEDENCE - 2;
。。。

将读取到的配置信息放到了Map中

public class CircuitBreakerConfigurationProperties extends CommonProperties {

    private Map<String, InstanceProperties> instances = new HashMap<>();
    private Map<String, InstanceProperties> configs = new HashMap<>();
  。。。
 }

提供了3中创建CircuitBreakerConfig的方法

    public CircuitBreakerConfig createCircuitBreakerConfig(String backendName,
        InstanceProperties instanceProperties,
        CompositeCustomizer<CircuitBreakerConfigCustomizer> compositeCircuitBreakerCustomizer) {
        // 如果配置项中有baseConfig,就去configs中找到baseConfig
        if (StringUtils.isNotEmpty(instanceProperties.getBaseConfig())) {
            InstanceProperties baseProperties = configs.get(instanceProperties.getBaseConfig());
            if (baseProperties == null) {
                throw new ConfigurationNotFoundException(instanceProperties.getBaseConfig());
            }
            //调用buildConfigFromBaseConfig方法创建创建CircuitBreakerConfig
            // 将baseProperties属性合并到 instanceProperties
            return buildConfigFromBaseConfig(instanceProperties, baseProperties,
                compositeCircuitBreakerCustomizer,
                backendName);
        }
        // 创建CircuitBreakerConfig
        return buildConfig(custom(), instanceProperties, compositeCircuitBreakerCustomizer,
            backendName);
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值