云计算设计模式(二)Circuit Breaker模式

Circuit Breaker Pattern/断路器模式

当应用程序连接到一个远程服务或者资源,并且服务或者资源需要一段时间才能恢复的时候,使用断路器模式可以提高应用程序的可靠性和容错性。


上下文和问题

在分布式环境中,调用远程服务或者资源,可能因为瞬时错误而失败。比如慢网络连接,超时,或者是资源过度使用或者临时不可用。这些错误一般情况下,会在很短的时间内自己修复。一个健壮的云端应用,应该使用某种策略重复处理它们,比如Retry模式。

然而,在有些情况下,错误是由不可预测的事件导致的,并且需要很长的事件才能修复。这些错误的严重程度,有可能从部分的连接丢失,蔓延到服务完全不可用。在这种情况下,应用程序不断的重试一些完全不可能成功的操作,可能是毫无意义的。应用程序应该快速接受操作已经失败,并且因此开始处理这些错误。

另外,如果系统非常繁忙,某些错误可能会导致级联反应。例如,一个调用其他服务的操作,可以被配置为实现了超时机制,如果服务没有在指定的时间内完成,将会返回一个错误信息。然而,这个策略可能会导致很多发送到相同操作的并发请求被锁,直到超时时间过期。这些被锁的请求可能持有了临界系统资源,比如内存,线程,数据库连接等等。这些资源可能被耗尽,导致需要使用相同资源的,系统不相关部分的失败。在这些情况下,优先的选择是使得这些操作立即失败,而在服务有可能成功时候,才去尝试调用他们。

注意:设置一个更短的超时时间可能有助于解决这个问题,但超时时间不应该被设置的太短,这样的话,会导致有些最终会成功的请求,大部分因超时失败。


解决方案

断路器模式会防止应用程序重复尝试去执行那些看起来会失败的操作。如果应用程序断定这个错误将持续很长时间,它将终止当前操作,而非等待错误被修复,或者浪费CPU时间周期。同时,断路器模式也会使得应用程序有能力探测错误是否被修复。如果问题看以来已经修复,应用程序可以尝试去调用这个操作。

断路器模式的目的和重试(Retry)模式是不同的,重试模式使得应用程序能够重试一个操作,期待它将会成功。而断路器模式阻止应用程序去调用那些看起来会失败的操作。应用程序可以合并这两种模式,通过断路器来使用重试模式调用一个操作,然而,重试逻辑应该对断路器返回的任何异常都是不敏感的,而且如果当断路器断定这个错误不是瞬时错误的话,应该放弃重试尝试。

断路器充当可能失败的操作的代理。这个代理应该监控最近发生的失败的次数,并根据最近失败的次数来决定这个操作是该继续进行,还是立即简单的返回一个异常信息。


断路器可以被实现为一个包含下列状态的状态机,以模拟电路断路器的功能:

1)已关闭(Closed)

来自应用程序的请求被路由到这个操作。代理维护了最近发生的错误的次数,如果一个调用操作未成功,代理将增加错误的次数。如果在给定时间内,最近失败的操作的次数超过了预先设置的阈值,代理将被设置为打开状态,这时,代理会启动一个超时计时器,当计时器过期,代理的状态将被设置为半打开(Half-Open)状态。

启动超时定时器的目的是为了在允许应用重新处理这个操作之前,给系统一些时间,让他可以修复导致失败的这些问题。

2)打开(Open)

在这个状态下,来自应用程序的请求会立刻失败,并返回异常信息

3)半打卡(Half-Open)

来自应用程序的有限数量的请求被允许通过,并调用操作。如果这些请求调用成功,断路器将假设之前导致调用失败的原因已经被修复,断路器会被设置成已关闭(Closed)状态(失败次数已回被重置)。如果仍有请求失败,断路器会假设问题仍然存在,并将状态回退到打开状态,并重新启动超时定时器,给系统一段更长的时间来修复导致失败的问题。

半打开(Half-Open)状态可以有效的防止刚刚恢复的服务被突如其来的请求淹没。作为服务恢复机制,它支持有限数量的请求通过,直到服务完全恢复;而不会因为在恢复过程中大量的请求到来致使请求超时或者再次失败。



如上图所示,被Closed状态使用的超时定时器是基于时间的,它会基于某个时间间隔,周期性的自动重置。这有助于防止断路器因为某些偶发的失败而进入Open状态。只有在指定的时间间隔内发生的失败次数达到设置的阈值时,才会触发断路器进入Open状态,Half-Open状态使用的计数器,会记录尝试调用某个操作成功的次数,如果任意一个调用失败了,那么断路器将立刻进入Open状态,并且在下次进入Half-Open状态时,调用成功次数的计数器将被重置。

系统如何恢复是由外部操作的(与断路器无关),可能是恢复或者重启失败的组件,也可能是恢复网络连接。


当系统刚刚从失败中恢复时,断路器模式提供了一种稳定机制,并且最小化性能方面的影响。它可以通过快速拒绝一个将会失败的请求,帮助维护系统的响应时间。而不是等待操作超时,或者是永远不会返回。如果断路器的状态每次发生变化时都会触发某些事件,这些事件可以用来帮助监控断路器所保护的那部分系统的健康状况;或者当断路器的状态变更为Open时,向管理员发出告警信息。


该模式是可定制的,可以根据可能的失败类型进行调整。例如,你可以为断路器设计一个递增的超时定时器,最开始断路器的状态设置为Open时,你可以设置定时器超时时间为几秒钟,如果故障没有解决,再将定时器的时间增加为几分钟,等等。在某些情况下,相比返回失败和一个程序异常,返回一个对应用程序来说有意义的默认值,可能更为有用。


问题和注意事项(Issues and Considerations)

当你决定如何实现断路器模式时,你应该考虑一下几点:

1)异常处理

应用通过断路器调用一个操作,必须准备处理当操作不可用的时候抛出的异常。处理异常的方式是由应用程序定义的。例如,应用程序可能临时降低级别,调用一个处理相同任务或者操作相同数据的替代操作;或者是将异常信息报告给用户,让他们稍后重试。

2)异常类型

请求失败可能有多种原因,其中有些失败可能比其他的失败更为严重,例如,有些失败可能是因为远程服务崩溃,需要花费几分钟的时间才能恢复;或者是因为服务临时过载,造成请求超时。断路器可能有能力判断发生的这些异常的类型,并根据异常的性质,采取不同的应对策略。例如,相比服务完全不可用错误,可能需要更大数量的服务超时的错误,才会让断路器切换到Open状态。

3)记录日志

断路器应该记录所有的错误请求日志(甚至是成功请求日志),使得管理员可以此为依据,监控操作的健康状态。

4)可恢复性

你应该配置断路器,为它保护的操作匹配最合适的恢复模式。如果断路器长时间维持在Open状态,即使错误已经被解决,仍然会抛出异常。同样的,如果断路器从Open状态切换到Half-Open状态太快的话,他也可能会有波动,并减少应用的相应次数。

5)测试失败操作

在Open状态下,如果不使用定时器来决定何时切换到Half-Open状态,断路器也可以周期性的PING远程服务或者资源,来判断它们是否已经变得可用。PING可以尝试调用以前失败的操作,或者它可以使用一个远程服务提供的特殊的操作来检查服务的健康状况,像健康端点监控器模式(Health Endpoint Monitor Pattern)描述的那样。

6)手动覆盖

在一个错误操作的恢复时间变动很大的系统中,提供一个手动的选项,使得管理员能够关闭一个断路器(或者重置失败计数器)是有益的。同样,如果定时器保护的操作临时不可用,管理员也可以强制断路器进入Open状态(或者重启超时定时器)。

7)并发性

同一个断路器可能被一个应用中大量实例并发访问,断路器的实现不应该阻塞并发的请求,或者给每个调用的操作代理过多额外的负担。

8)资源区分

如果断路器使用一种资源,而这个资源可能有多个独立的提供者的时候,要格外小心。比如说,在一个数据存储中,其中一个数据存储完全可用,而其他的可能临时有问题。如果这些场景的错误被合并,那么,应用尝试访问一些很大可能失败的分片时,会导致操作失败,这将会使得对于其他完全正常的分片的访问,也可能被阻塞。

9)加速断路

有的时候,一个失败的响应可能包含足够的信息,使得断路器立即开启,并开启一小段时间。例如,一个来自共享资源过载的错误的响应,能够让断路器立即判断出,不建议立即重试,应用程序应该等几分钟再重试。

注意:服务如果正在阻塞客户端,它可能返回HTTP 429(太多请求);或者如果服务当前不可用,它可能返回503。服务可能返回附加的信息,比如预期的延迟时间。

10)回放错误请求

在Open状态下,除了立即返回错误之外,断路器也可以记录这些请求的明细信息到一个队列中,当远程服务或者资源重新可用时,可以安排这些请求重放。

11)不合适的外部服务超时

断路器可能无法完全保护配置了超长超时时间的外部服务的请求失败。如果超时时间太长,运行断路器的线程在判断请求失败之前,会被阻塞更长的时间(超过外部服务的超时时间),在这段时间内,很多其他的应用实例也会尝试通过断路器调用这个服务,在这些调用都失败之前,这将会挂起大量的线程。


何时使用本模式

1)阻止应用程序访问一个有很大可能失败的远程服务或者资源


如下场景不推荐使用本模式:

1)如果应用程序访问的是本地私有资源,比如内存数据结构;在这种情况下,使用断路器将会增加系统的负担

2)在应用程序的业务逻辑中,作为异常处理的替代品(断路器模式的本质是为了防止调用很大可能会失败的操作,而不是为了处理异常)


相关的设计模式:

在实现断路器模式时,下列模式可能是有用的:

1)重试模式(Retry Pattern),描述了一个应用程序在连接到一个服务或者资源时,如何通过透明的重新调用一个之前失败了的操作,来处理预期的临时失败。

2)健康端点监控模式(Health Endpoint Monitor Pattern),断路器可能会通过调用远程服务或者资源暴露的接口,来检查其健康状态,这个接口可以返回表示自己状态的信息。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值