• Hystrix 熔断机制原理


    相关配置

    circuitBreaker.enabled  是否开启熔断
    circuitBreaker.requestVolumeThreshold  熔断最低触发请求数阈值
    circuitBreaker.sleepWindowInMilliseconds  产生熔断后恢复窗口
    circuitBreaker.errorThresholdPercentage  错误率阈值
    circuitBreaker.forceOpen  强制打开熔断
    circuitBreaker.forceClosed  强制关闭熔断
    

    状态图

    image

    执行流程

    命令执行前调用circuitBreaker.attemptExecution(),正常情况下会执行返回true,但是如果发生熔断,则需要通过sleepWindows来进行恢复

    public boolean attemptExecution() {
        if (properties.circuitBreakerForceOpen().get()) {
            return false;
        }
        if (properties.circuitBreakerForceClosed().get()) {
            return true;
        }
        if (circuitOpened.get() == -1) {
            return true;
        } else {
            if (isAfterSleepWindow()) {
                if (status.compareAndSet(Status.OPEN, Status.HALF_OPEN)) {
                    //only the first request after sleep window should execute
                    return true;
                } else {
                    return false;
                }
            } else {
                return false;
            }
        }
    }
    

    发生熔断流程

    在新版本1.5.12中,会有一个后台线程订阅metrics流实时计算:

    1. 如果没有达到RequestVolume,则直接返回,不计算是否需要熔断
    2. 如果当前错误率大于设置的阈值,则触发熔断,状态由CLOSED切换到OPEN,并设置当前熔断的时间(用于后续SleepWindows判断使用)
    if (hc.getTotalRequests() < properties.circuitBreakerRequestVolumeThreshold().get()) {
        // we are not past the minimum volume threshold for the stat window,
        // so no change to circuit status.
        // if it was CLOSED, it stays CLOSED
        // if it was half-open, we need to wait for a successful command execution
        // if it was open, we need to wait for sleep window to elapse
    } else {
        if (hc.getErrorPercentage() < properties.circuitBreakerErrorThresholdPercentage().get()) {
            //we are not past the minimum error threshold for the stat window,
            // so no change to circuit status.
            // if it was CLOSED, it stays CLOSED
            // if it was half-open, we need to wait for a successful command execution
            // if it was open, we need to wait for sleep window to elapse
        } else {
            // our failure rate is too high, we need to set the state to OPEN
            if (status.compareAndSet(Status.CLOSED, Status.OPEN)) {
                circuitOpened.set(System.currentTimeMillis());
            }
        }
    }
    

    熔断恢复流程

     当发生熔断,达到SleepWindows指定时间后,则状态会由OPEN转换为HALF_OPEN,此时只会让一个请求通过,如果该请求执行成功,状态则会转换为CLOSED,否则会回到OPEN状态,并且熔断时间设置为当前时间,重新等待SleepWindows的时间

    // 执行成功后调用
    public void markSuccess() {
        if (status.compareAndSet(Status.HALF_OPEN, Status.CLOSED)) {
            //This thread wins the race to close the circuit - it resets the stream to start it over from 0
            metrics.resetStream();
            Subscription previousSubscription = activeSubscription.get();
            if (previousSubscription != null) {
                previousSubscription.unsubscribe();
            }
            Subscription newSubscription = subscribeToStream();
            activeSubscription.set(newSubscription);
            circuitOpened.set(-1L);
        }
    }
    
    // 执行失败后调用
    public void markNonSuccess() {
        if (status.compareAndSet(Status.HALF_OPEN, Status.OPEN)) {
            //This thread wins the race to re-open the circuit - it resets the start time for the sleep window
            circuitOpened.set(System.currentTimeMillis());
        }
    }
    

    参考

    1. https://github.com/Netflix/Hystrix/wiki/Configuration
    2. https://github.com/Netflix/Hystrix/wiki/How-it-Works#CircuitBreaker
    3. HystrixCircuitBreaker源码
  • 相关阅读:
    Object添加Symbol.iterator办法执行for--of
    二十四节气
    正则
    内容换行展示
    textarea 友好提示
    yyyy-MM-dd
    Repeater和PagedDataSource 绑定数据
    刷新 跳转 关闭 时弹窗
    SqlParameter CommandType.Text CommandType.StoredProcedure;
    JQuery disabled(禁用启用按钮)和display
  • 原文地址:https://www.cnblogs.com/jabnih/p/9013197.html
Copyright © 2020-2023  润新知