我的一个同事问我这个问题:断路器和重试的区别是什么,但我不能正确地回答他。我只知道,如果有大量的请求负载,断路器很有用,但是这也可以使用重试来实现。那么,何时使用断路器,何时重试呢?
另外,是否可能在同一个API上同时使用两种方法?
我的一个同事问我这个问题:断路器和重试的区别是什么,但我不能正确地回答他。我只知道,如果有大量的请求负载,断路器很有用,但是这也可以使用重试来实现。那么,何时使用断路器,何时重试呢?
另外,是否可能在同一个API上同时使用两种方法?
几年前,我写了一个弹性目录来描述不同的机制。最初我为同事创建了这个文档,然后我公开分享了它。请允许我在此引用相关部分。
类别: 响应式、事后
重试和尝试之间的关系:n次重试意味着最多n+1次尝试。+1是初始请求,如果失败(无论什么原因),则重试逻辑会启动。换句话说,第0步执行时不会有延迟惩罚。
有些情况下,您请求的操作依赖于某个资源,该资源在某个时间点可能无法访问。换句话说,可能存在暂时性问题,这些问题迟早会消失。这种问题可能会导致瞬态故障。通过重试,您可以在将来的特定时刻尝试重新执行相同的操作以克服这些问题。为了能够使用此机制,必须满足以下标准组:
让我们逐一审查它们:
分类:主动型,事前预防
很难将断路器归类为主动型或者被动型,因为它同时具备这两种特性。它能够检测出给定的下游系统故障(被动型),并且保护下游系统免受新请求的淹没(主动型)。
这是最复杂的设计模式之一,主要因为它使用了不同的状态来定义不同的行为。在我们深入了解细节之前,让我们看看为什么需要使用这个工具:
断路器可以检测失败,并防止应用程序尝试执行注定失败的操作(直到安全重试为止) - Wikipedia
因此,这个工具作为一个 mini 数据和控制平面发挥作用。请求通过该代理进行,该代理检查响应(如果有的话)并计算后续的失败次数。如果达到预定的阈值,传输将暂时停止并立即失败。
它可以防止级联故障。换句话说,下游系统的短暂故障不应该传播到上游系统。通过隐藏故障,我们实际上防止了连锁反应(多米诺骨牌效应)。
它必须某种方式确定何时再次作为代理安全运行。例如,它可以使用在原始故障检测期间使用的相同检测机制。因此,它的工作方式如下:在一定时间后,它允许单个请求通过,并检查响应。如果成功,则将下游视为健康。否则,什么也不会改变(没有请求通过此代理),只有计时器被重置。
断路器可以处于以下任何状态:关闭
、打开
、半开
。
Closed
:它允许任何请求。它计算连续失败的请求次数。
Open
Open
:它立即拒绝任何请求。它等待预定义的一段时间。
HalfOpen
HalfOpen
:它只允许一个请求。它检查该请求的响应:
Closed
Open
上述两种机制/策略并不是相互排斥的,相反,它们可以通过升级机制进行组合。如果内部策略无法处理问题,则可以向外部策略传播一级。
当您在断路器处于Open
状态时尝试执行请求,它将抛出异常。您的重试策略可以触发并调整其睡眠时间(以避免不必要的尝试)。
下游系统还可以通知上游它正在收到太多带有429状态码的请求。断路器也可以为此触发,并使用Retry-After
头的值作为其睡眠时间。
因此,本节的整个重点是您可以定义客户端和服务器之间如何共同克服瞬态故障的协议。
重试模式使应用程序可以重试操作以期成功。
断路器模式可以防止应用程序执行可能失败的操作。
重试 - 重试模式在瞬时故障的情况下非常有用。这是什么意思?只持续很短时间的“临时”故障是瞬时故障。网络连接的暂时中断、服务暂时关闭或无响应以及相关超时等都是瞬时故障的示例。
由于故障是瞬时的,稍后重试可能会给我们带来所需的结果。
断路器 - 断路器模式在长时间的故障情况下非常有用。考虑到连接中断或需要一些时间才能修复的服务故障。在这种情况下,如果确实需要一段时间才能从服务器那里得到回应,经常重试可能没有多大用处。断路器模式旨在防止应用程序执行可能失败的操作。
断路器会记录最近故障的数量,并根据预定的阈值确定是否应该将请求发送给受压力的服务器。