Spring Boot微服务中的断路器和重试有什么区别?

Sat*_*ash 3 circuit-breaker spring-boot microservices retry-logic resilience4j-retry

我的一位同事问我这个问题,断路器和重试之间有什么区别,但我无法正确回答他。据我所知,如果请求负载很大,断路器很有用,但这可以通过重试来实现。然后何时使用断路器以及何时重试。

另外,是否可以在同一个 API 上使用两者?

Pet*_*ala 7

几年前,我写了一个弹性目录来描述不同的机制。最初我为同事创建了此文档,然后公开共享。请允许我在这里引用相关部分。

\n

重试

\n

类别:反应性、事后

\n
\n

重试和尝试的关系:n次重试意味着最多n+1次尝试。+1 是初始请求,如果失败(无论出于何种原因),则重试逻辑启动。换句话说,第 0 步以 0 延迟惩罚执行。

\n
\n

在某些情况下,您请求的操作依赖于某个资源,而该资源在某个时间点可能无法访问。换句话说,可能存在一个暂时的问题,这个问题迟早会消失。此类问题可能会导致暂时性故障。通过重试,您可以通过尝试在未来的特定时刻重做相同的操作来克服这些问题。为了能够使用此机制,应满足以下标准组:

\n
    \n
  • 潜在引入的可观察影响是可以接受的
  • \n
  • 手术可以重做,没有任何不可逆的副作用
  • \n
  • 与承诺的可靠性相比,引入的复杂性可以忽略不计
  • \n
\n

让\xe2\x80\x99s一一回顾一下:

\n
    \n
  • “失败”一词表示请求者也可以观察到效果,例如通过更高的延迟/降低的吞吐量等。如果 \xe2\x80\x9cpenalty\xe2\x80\x9c (延迟或性能降低)不可接受,则重试不是您的选择。
  • \n
  • 此要求也称为幂等操作。如果我多次使用相同的输入调用该操作,那么它将产生完全相同的结果。换句话说,该操作的行为就像它仅取决于其参数,而没有其他因素影响结果(就像其他对象的状态一样)。
  • \n
  • 尽管这一条件是最重要的条件之一,但它却几乎总是被遗忘。一如既往,需要权衡(如果我引入 Z,那么它会增加 X,但可能会减少 Y)。\n
      \n
    • 我们应该充分认识到它们,否则会在最意想不到的时间内给我们带来一些意想不到的惊喜。
    • \n
    \n
  • \n
\n

断路器

\n

类别: 主动、事前

\n
\n

很难对断路器进行分类,因为它同时具有主动性和被动性。它检测到给定的下游系统发生故障(反应性),并保护下游系统免受新请求的淹没(主动性)。

\n
\n

这是最复杂的模式之一,主要是因为它使用不同的状态来定义不同的行为。在我们深入了解细节之前,让我们先看看为什么这个工具存在:

\n

断路器检测故障并阻止应用程序尝试执行注定会失败的操作(直到可以安全地重试) -维基百科

\n

因此,该工具充当迷你数据控制平面。请求通过该代理,该代理检查响应(如果有)并计算后续失败的数量。如果达到预定义的阈值,则传输将暂时暂停并立即失败。

\n
    \n
  • 为什么它有用?
  • \n
\n

它可以防止级联故障。换句话说,下游系统的瞬时故障不应传播到上游系统。通过隐瞒故障,我们实际上也防止了连锁反应(多米诺骨牌效应)。

\n
    \n
  • 它如何知道暂时性故障何时消失?
  • \n
\n

它必须以某种方式确定何时可以安全地再次作为代理运行。例如,它可以使用与原始故障检测期间使用的相同的检测机制。因此,它的工作原理如下:在给定的时间段后,它允许单个请求通过并检查响应。如果成功,则下游被视为健康。否则,不会发生任何变化(不会通过此代理传输任何请求),只会重置计时器。

\n
    \n
  • 它使用什么状态?
  • \n
\n

断路器可以处于以下任意状态:ClosedOpenHalfOpen

\n
    \n
  • Closed:它允许任何请求。它对连续失败的请求进行计数。\n
      \n
    • 如果连续失败计数低于阈值并且下一个请求成功,则计数器将设置回 0。
    • \n
    • 如果达到预定义阈值,则转换为Open
    • \n
    \n
  • \n
  • Open:它立即拒绝任何请求。它等待预定义的时间。\n
      \n
    • 如果该时间过去了,那么它就会转变为HalfOpen
    • \n
    \n
  • \n
  • HalfOpen: 只允许一个请求。它检查该请求的响应:\n
      \n
    • 如果响应表明成功,则它会转换为Closed
    • \n
    • 如果响应指示失败,则它会转换回Open
    • \n
    \n
  • \n
\n

弹性策略

\n

相反,上述两种机制/政策并不相互排斥。它们可以通过升级机制进行组合。如果内部策略无法处理问题,它可以将问题向上传播到外部策略。

\n

当您尝试在断路器处于状态时执行请求时,Open它将引发异常。您的重试策略可能会触发该操作并调整其睡眠持续时间(以避免不必要的尝试)。

\n

下游系统还可以通过429 状态代码通知上游它收到的请求过多。断路器也可以为此触发并使用Retry-After标头的值作为其睡眠持续时间。

\n

因此,本节的重点是您可以在客户端和服务器之间定义一个协议,如何共同克服暂时性故障。

\n