01、Sentinel 源码分析 之 断路器实现原理
开始断路器相关内容的学习。
1、断路器介绍
断路器通过有限状态机实现,该有限状态机有三种正常状态: CLOSED(闭合) 、 OPEN(打开) 和 HALF_OPEN(半打开),以及两种特殊状态: DISABLED(禁用) 和 FORCED_OPEN(强制打开)。

断路器使用滑动窗口存储和统计调用的结果。可以选择 基于计数的滑动窗口 和 基于时间的滑动窗口。
- 基于计数的滑动窗口汇总统计最近N次调用的结果。
- 基于时间的滑动窗口将统计最近N秒的调用结果。
2、基于访问数量的滑动窗口
基于计数的滑动窗口是用一个 N 个测量值的圆形数组来实现的。
如果 count 窗口大小为 10,则循环数组总是有 10 个度量值。
滑动窗口增量更新总的统计值,随着新的调用结果被记录在环形数组中,总的统计值也随之进行更新。当环形数组满了,时间最久的元素将被驱逐,将从总的统计值中减去该元素的统计值,并该元素所在的桶进行重置。
检索快照(总的统计值)的时间复杂度为O(1),因为快照已经预先统计好了,并且和滑动窗口大小无关。
关于此方法实现的空间需求(内存消耗)为O(n)。
3、基于时间的滑动窗口
基于时间的滑动窗口是通过有 N 个桶的环形数组实现。
如果滑动窗口的大小为10秒,这个环形数组总是有10个桶,每个桶统计了在这一秒发生的所有调用的结果(部分统计结果),数组中的第一个桶存储了当前这一秒内的所有调用的结果,其他的桶存储了之前每秒调用的结果。
滑动窗口不会单独存储所有的调用结果,而是对每个桶内的统计结果和总的统计值进行增量的更新,当新的调用结果被记录时,总的统计值会进行增量更新。
检索快照(总的统计值)的时间复杂度为 O(1),因为快照已经预先统计好了,并且和滑动窗口大小无关。
关于此方法实现的空间需求(内存消耗)约等于O(n)。由于每次调用结果(元组)不会被单独存储,只是对N个桶进行单独统计和一次总分的统计。
每个桶在进行部分统计时存在三个整型,为了计算,失败调用数,慢调用数,总调用数。还有一个long类型变量,存储所有调用的响应时间。
4、失败率和慢调用率阈值
当失败率大于或等于配置的阈值时,断路器的状态将从关闭变为开启,例如,当超过 50% 的调用失败时,断路器开启。
默认是把所有的异常看作是失败,你可以自己定义一个异常的列表,这些异常会被视为错误,其他的异常会被视为调用成功,除非是可以被忽略的异常。异常是可以被忽略的,这样它们既不算成功也不是算失败。
当慢调用的百分比大于等于配置的阈值时,断路器的状态将从关闭变为开启,例如,当超过 50% 的调用响应时间超过 5 秒时,断路器开启,这有助于在外部系统实际上没有响应之前减少它的负载。
只有在记录了最小调用次数的情况下,才能计算失败率和慢调用率。例如,如果所需调用的最小数目为 10,则必须至少记录 10 个调用,然后才能计算失败率。如果只记录了 9 个调用,即使所有 9 个调用都失败,断路器也不会开启。
断路器在开启时,将会使用 CallNotPermittedException 来拒绝请求。在一段时间之后,断路器的状态将从开启变为半开,并且允许一定数量的调用通过,来判断后端的服务是否还是不可用或已变为可用,在所有允许通过断路器的调用完成之前,其余的调用还是被 CallNotPermittedException 拒绝。如果失败率或慢调用率大于等于配置的阈值,断路器状态将继续回到开启,如果失败率和慢调用率低于配置的阈值,断路器状态变为关闭。
断路器还支持两种特殊的状态,禁用(总是允许访问)和强制开启(总是拒绝访问)。在这两种状态下,不会产生断路器事件(除了状态转换),也不会记录任何指标。退出这些状态的唯一方法是触发状态转换或重置断路器。
断路器是线程安全的:
- 断路器的状态是原子引用。
- 断路器使用原子操作以无副作用的功能来更新状态。
- 从滑动窗口中记录调用结果和读取快照是同步的。
这意味着原子性得到了保证,在某一时刻,只允许一个线程对断路器的状态进行更改,和对滑动窗口进行操作。
但是断路器不会同步方法调用,这意味着方法调用不是核心的部分。否则,短路器将会带来大量的性能损失和瓶颈,耗时的方法调用会对整体性能/吞吐量带来巨大的负面影响。
如果有 20 个并发线程想要执行某个函数,并且断路器的状态为关闭,所有的线程都被允许进行方法调用,即使假设滑动窗口的大小是15,也不意味滑动窗口只允许 15 个调用并发的执行。如果你想要限制并发线程的数量,需要使用隔离机制,将隔离机制和断路器组合使用。
一个线程的例子:

三个线程的例子:

原文地址:
- Resilience4j-Guides-Chinese
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
