每日一句
过去的要靠现在忘记,将来的要靠现在努力,所以现在最重要!
介绍
CircuitBreaker通过具有三种正常状态的有限状态机实现:CLOSED,OPEN和HALF_OPEN以及两个特殊状态DISABLED和FORCED_OPEN。
滑动窗口
CircuitBreaker使用滑动窗口来存储和汇总执行结果。可以在基于计数的滑动窗口和基于时间的滑动窗口之间进行选择。基于计数的滑动窗口会汇总最近N次调用的结果。基于时间的滑动窗口会汇总最近N秒的调用结果。
基于计数的滑动窗口
基于计数的滑动窗口由N个测量值的圆形数组实现。
如果计数窗口大小为10,则圆形阵列始终具有10个测量值。
滑动窗口以增量方式更新总聚合。当记录新的呼叫结果时,将更新总汇总。收回最旧的度量后,将从总聚合中减去该度量,然后重置存储桶。(逐项扣除)
快照的获取时间为常数O(1),因为快照是预先聚合的,并且与窗口大小无关。
此实现的空间需求(内存消耗)应为O(n)。
基于时间的滑动窗口
基于时间的滑动窗口是由N个部分集合(存储桶)的圆形数组实现的。
如果时间窗口大小为10秒,则圆形数组始终具有10个部分聚合(存储桶)。每个存储桶都会汇总在某个时期内发生的所有调用的结果。(部分聚集)。圆形数组的头存储区存储当前纪元的呼叫结果。其他部分聚合存储前几秒的呼叫结果。
滑动窗口不会单独存储呼叫结果(元组),而是以增量方式更新部分聚合(存储桶)和总聚合。
当记录新的呼叫结果时,总聚合将增量更新。当最旧的存储桶被收回时,该存储桶的部分总聚合将从总聚合中减去,然后重置该存储桶。(逐项扣除)
快照的获取时间为常数O(1),因为快照是预先聚合的,并且与时间窗口的大小无关。
此实现的空间需求(内存消耗)应接近常数O(n),因为调用结果(元组)不是单独存储的。仅创建N个部分聚合和1个总聚合。
部分聚合由3个整数组成,以计算失败的呼叫数,慢速呼叫数和总呼叫数。一个长存储所有呼叫的总持续时间。
故障率和慢呼率阈值
当故障率等于或大于可配置的阈值时,CircuitBreaker的状态将从“关闭”更改为“打开”。例如,当超过50%的录制呼叫失败时。
默认情况下,所有异常均视为失败。您可以定义应视为失败的异常列表。除非忽略所有其他异常,否则所有其他异常均被视为成功。也可以忽略异常,这样它们既不算作失败也不算成功。
当慢速呼叫的百分比等于或大于可配置的阈值时,CircuitBreaker也会从CLOSED变为OPEN。例如,当超过50%的录音通话时间超过5秒。这有助于在外部系统实际上没有响应之前减轻其负担。
如果记录了最小数量的呼叫,则只能计算故障率和慢速呼叫率。例如,如果所需呼叫的最小数量为10,则必须至少记录10个呼叫,然后才能计算故障率。如果仅评估了9个呼叫,则即使所有9个呼叫均失败,CircuitBreaker也不会跳闸。
CircuitBreaker处于OPEN时拒绝呼叫。经过一段等待时间后,CircuitBreaker状态从OPEN变为HALF_OPEN,并允许可配置数量的呼叫以查看后端是否仍然不可用或再次变为可用。用拒绝其他呼叫,直到所有允许的呼叫完成。 如果故障率或慢呼叫率等于或大于配置的阈值,则状态会变回OPEN。如果故障率和慢呼叫率低于阈值,则状态将更改回CLOSED。CallNotPermittedExceptionCallNotPermittedException
断路器支持另外两种特殊状态,即DISABLED(始终允许访问)和FORCED_OPEN(始终拒绝访问)。在这两种状态下,不会生成任何断路器事件(状态转换除外),也不会记录任何度量。退出这些状态的唯一方法是触发状态转换或重置断路器。
CircuitBreaker是线程安全的,如下所示:
CircuitBreaker的状态存储在AtomicReference中
CircuitBreaker使用原子操作来更新无副作用功能的状态。
从“滑动窗口”记录呼叫和读取快照已同步
这意味着应该保证原子性,并且只有一个线程能够在某个时间点更新状态或“滑动窗口”。
但是CircuitBreaker不会同步功能调用。这意味着函数调用本身不是关键部分的一部分。否则,CircuitBreaker会带来巨大的性能损失和瓶颈。缓慢的函数调用会对整体性能/吞吐量产生巨大的负面影响。
如果有20个并发线程请求执行功能的许可,并且CircuitBreaker的状态关闭,则允许所有线程调用该功能。即使滑动窗口的大小为15。滑动窗口也不意味着仅允许15个调用并发运行。如果要限制并发线程数,请使用Bulkhead。您可以结合使用隔板和CircuitBreaker。
具有一个线程的示例:
具有多个线程的示例:
官网总结
官网对于Resilience4j-Circuit Breaker的介绍就到者。后面我们将站在使用的角度以及深入源码对上面的理论逐一分析。