当前位置: 首页 > 知识库问答 >
问题:

波利断路器能承受指数级的断路持续时间吗?

闻人嘉木
2023-03-14

当由于用尽连接池而收到超时异常时,我们正试图为数据库逻辑实现重试策略。当我们在一段较小的时间内异常大的活动激增时,就会发生这种情况。我们已经增加了最大池大小以避免这种情况,但我们也希望重试逻辑作为备份计划。

连池留档说明:

启用连接池时,如果出现超时错误或其他登录错误,将引发异常,随后的连接尝试将在接下来的五秒钟内失败,即“阻塞期”。如果应用程序试图在阻塞期内连接,将再次引发第一个异常。阻塞期结束后的后续故障将导致新的阻塞期,其长度是前一个阻塞期的两倍,最长可达一分钟。

Polly似乎非常适合解决这一问题,通过将回退、等待和重试以及断路器策略相结合的PolicyWrap策略。这里有一张很好的照片

理想情况下,我希望能够为断路器指定指数持续时间,以匹配上述倍增周期。我还没有在网上看到任何这样做的例子,所以也许这是不可能的?

这里想要的配置方法是什么?是否指定断路器的断开持续时间为5秒,然后对等待和重试组件使用指数重试时间(5、10、20、40和60秒)?这似乎很不幸,因为连接刚刚可用,旧操作刚刚开始40秒的等待,而新操作将立即工作。

另一种可能性是5秒的中断时间,然后让WaitAndRetry组件使用一个非常小的等待时间,并进行大量重试,尽管我们知道,如果这些重试在文档状态之前进行,其中许多将失败。

感谢您的反馈!

共有1个答案

谭泳
2023-03-14

Polly不提供具有不同(例如指数)断开持续时间的断路器。

以下内容乍一看可能与直觉相悖,但:听上去,这种情况似乎不需要具有指数回退功能的断路器,因为ADO。描述的网络连接池算法已经有效地提供了这一点。

理由:断路器的目的是停止向不太可能处理它们的下游系统发送呼叫,以便:(a)快速向呼叫方发送故障;(b) 保护底层系统不受过度负载的影响。听起来像是在胡闹。NET的算法已经实现了这两个目标。

类似地,指数退避重试策略的目标是防止重试本身“增加”负载(在基础系统上创建自诱导的DDOS攻击……更多请求进入,现有请求也在重试)。同样,这听起来像是胡闹。NET的强制退避算法正在强制执行自己的指数退避,以保护底层数据库,因此,将自己的Polly指数退避放在上面可能没有任何好处(*)。

基于ADO。NET提供了自己的防御,我很想做一些简单的事情,比如使用重试策略,固定重试间隔为5秒或5秒以上。(无论“封锁期”是什么,似乎都是5秒的倍数。)

这个建议是基于一个假设,即ADO. NET连接池管理(在这个阻塞期内)都发生在调用方;即嵌入在调用应用程序中的ADO. NET代码正在决定其连接池被充分利用,并拒绝阻塞中的进一步连接尝试期间不把网络调用传递到底层SQL服务器来检查。如果该假设不正确,那么上面的建议(*)可能是错误的,最好使用指数退避重试策略来避免连接重试尝试使数据库服务器过载。

注意:我没有直接与这个特殊的ADO合作。净限额。那些有经验的人可能会有更好的建议。那些了解内部事务的人。NET architecture better可能更清楚每五秒钟进行一次尝试(正如我所建议的)会有多“昂贵”,但可能会被拒绝。

附录:本讨论还忽略了调用程序中导致线程/CPU不足或类似情况的高并行需求的任何方面。如果这是一个问题,考虑在某些已知的容许极限下主动的甩负荷。

 类似资料:
  • 注:本节未经校验,如有问题欢迎提issue 为什么使用它们? 线路断路器用于提供稳定性并防止在分布式系统中的级联故障。它们应该结合在远程系统之间的接口使用明智的超时,以防止单个组件的故障拖垮所有组件。 作为一个例子,我们有一个web 应用程序与远程的第三方web服务进行交互。假如第三方已用完了他们的容量,他们的数据库也在高荷载作用下熔化。假设数据库在这种情况下失败,第三方 web 服务用了很长的时

  • 在一个节点失败的情况下,断路器可以避免这个错误影响其他服务,以免出现雪崩的情况。查看断路器的详细介绍: Pattern: Circuit Breaker. 客户端通过断路器调用服务, 一旦连续的错误达到一个阈值,断路器就会断开进行保护,这个时候如果还调用这个节点的话,直接就返回错误。等一定的时间,断路器会处于半开的状态,允许一定数量的请求尝试发送这个节点,如果正常访问,断路器就处于全开的状态,否则

  • 我正在尝试春云和春靴。它使用了Netflix的OSS应用程序,其中有Ribbon和Hystrix。 Ribbon是一个负载均衡器,带有一些功能,其中一个是断路器。

  • 我在我的spring boot应用程序中使用Hystrix实现断路器,我的代码如下所示: 我看到每次失败时都会调用fallback()。但3次故障后电路不开。在3次失败之后,我原以为它会直接调用并跳过。但这并没有发生。有人能告诉我我在这里做错了什么吗? 谢谢,B Jagan 下面是实际代码。我用这个玩得更远了。当我在RegistrationHystrix.RegisterSeller()方法中直接

  • 我在Angular 2中有这样一个组件(alpha版本49): 它工作得非常好。今天我把我的角版升级到了2.0.0-beta.0。现在上面的代码失败与消息: 我在哪里犯了一个错误?更改日志对此只字未提。