Spring Cloud--hystrix熔断的原理

原文网址:Spring Cloud--hystrix熔断的原理_IT利刃出鞘的博客-CSDN博客

简介

本文介绍SpringCloud的hystrix的断路器的原理。

本内容也是Java后端面试常见的问题。

原理

简述

断路器是如何决策熔断和记录信息的呢?

看断路器HystrixCircuitBreaker的定义:

public interface HystrixCircuitBreaker {
	public static class Factory {...}
	static class HystrixCircuitBreakerlmpl implements HystrixCircuitBreaker {… }
	static class NoOpCircuitBreaker implements HystrixCircuitBreaker {… }
	public boolean allowRequest();
	public boolean isOpen();
	void markSuccess() ;
}

可以看到它的接口定义并不复杂,主要定义了三个断路器的抽象方法。

  • allowRequest():判断是否允许执行Hystrix命令的请求。
  • isOpen():返回当前断路器是否打开。
  • markSuccess():用来闭合断路器。

另外还有三个静态类。

  1. 静态类Factory中维护了一个Hystrix命令与HystrixCircuitBreaker的关系集合:ConcurrentHashMap<String,HystrixCircuitBreaker>cpircuitBreakersByCommand,其中String类型的key通过HystrixCommandKey定义,每一个Hystrix命令需要有一个key来标识,同时一个Hystrix命令也会在该集合中找到它对应的断路器HystrixCircuitBreaker实例。
  2. 静态类NoOpCircuitBreaker定义了一个什么都不做的断路器实现,它允许所有请求,并且断路器状态始终闭合。
  3. 静态类HystrixCircuitBreakerlmpl是断路器接口HystrixCircuitBreaker的实现类,在该类中定义了断路器的4个核心对象。
    1. HystrixCommandPropertiesproperties:断路器对应HystrixCommand实例的属性对象,它的详细内容我们将在后续章节做具体的介绍。 
    2. HystrixCommandMetricsmetrics:用来让HystrixCommand记录各类度量指标的对象。
    3. AtomicBooleancircuitOpen:断路器是否打开的标志,默认为false。
    4. AtomicLongcircuitOpenedOrLastTestedTime:断路器打开或是上一次测试的时间戳。

HystrixCircuitBreakerlmpl对HystrixCircuitBreaker接口的各个方法实现如下所示。

isOpen()

判断断路器的打开/关闭状态。

  1. 如果断路器打开标识为true,则直接返回true,表示断路器处于打开状态。
  2. 如果断路器打开标识为false,就从度量指标对象metrics中获取HealthCounts统计对象做进一步判断(该对象记录了一个滚动时间窗内的请求信息快照,默认时间窗为10秒)。
    1. 如果错误百分比在阈值范围内就返回false,表示断路器处于未打开状态。
      1. 该阈值的配置参数为circuitBreakerErrorThresholdPercentage,默认值为50。
    2. 如果它的请求总数(QPS)在预设的阈值范围内就返回false,表示断路器处于未打开状态。
      1. 该阈值的配置参数为circuitBreakerRequestVolumeThreshold,默认值为20。
    3. 如果上面的两个条件都不满足,则将断路器设置为打开状态(熔断/短路)。
      1. 如果是从关闭状态切换到打开状态的话,就将当前时间记录到上面提到的circuitOpenedOrLastTestedTime对象中。

isOpen()源码 

@Override
public boolean isOpen() {
    if (circuitOpen.get()) {
        // if we're open we immediately return true and don't bother attempting to 'close' ourself as that is left to allowSingleTest and a subsequent successful test to close
        return true;
    }

    // we're closed, so let's see if errors have made us so we should trip the circuit open
    HealthCounts health = metrics.getHealthCounts();

    // check if we are past the statisticalWindowVolumeThreshold
    if (health.getTotalRequests() < properties.circuitBreakerRequestVolumeThreshold().get()) {
        // we are not past the minimum volume threshold for the statisticalWindow so we'll return false immediately and not calculate anything
        return false;
    }

    if (health.getErrorPercentage() < properties.circuitBreakerErrorThresholdPercentage().get()) {
        return false;
    } else {
        if (circuitOpen.compareAndSet(false, true)) {
            circuitOpenedOrLastTestedTime.set(System.currentTimeMillis());
            return true;
        } else {
            // How could previousValue be true? If another thread was going through this code at the same time a race-condition could have
            // caused another thread to set it to true already even though we were in the process of doing the same
            // In this case, we know the circuit is open, so let the other thread set the currentTime and report back that the circuit is open
            return true;
        }
    }
}

allowRequest()

作用:判断请求是否被允许。

上边只是部分内容,为便于维护,本文已迁移到此地址:Spring Cloud-hystrix熔断的原理 - 自学精灵

  • 8
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IT利刃出鞘

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值