当由于耗尽连接池而收到超时异常时,我们正在尝试为数据库逻辑实施重试策略。当我们在短时间内出现异常大量活动的峰值时,就会发生这种情况。为了避免这种情况,我们增加了最大池大小,但是我们也希望将重试逻辑作为备份计划。
documentation for connection pooling指出:
启用连接池后,如果发生超时错误或其他登录错误,则将引发异常,并且随后的连接尝试将在接下来的五秒钟(“阻塞时间段”)中失败。如果应用程序在阻塞时间内尝试连接,则将再次引发第一个异常。阻塞时间段结束后发生的后续故障将导致新的阻塞时间段,该时间段是上一个阻塞时间段的两倍,最长为一分钟。
通过回退,WaitAndRetry和Circuit Breaker策略的PolicyWrap组合,Polly似乎非常适合解决此问题。这个here
很好理想情况下,我希望能够为断路器指定一个指数的durationBreak以匹配上述倍增周期。我还没有在网上看到任何有关如何做到这一点的例子,所以也许这不可能吗?
这里所需的配置方法是什么?是否要指定一个具有5秒durationOfBreak的断路器,然后对WaitAndRetry组件使用5、10、20、40和60秒的指数重试?对于刚刚可用的连接,您的旧操作刚刚开始等待40秒钟,而新操作将立即生效,这似乎是不幸的。
另一种可能性是具有5秒钟的durationBBreak,然后让WaitAndRetry组件使用非常小的等待并进行大量重试,即使我们知道许多重试如果在文档状态之前都将失败。
感谢您的反馈!
答案 0 :(得分:2)
Polly不为断路器提供不同的(例如指数的)断开持续时间。
下面的内容乍看起来似乎是违反直觉的,但是:听起来好像这种情况不需要具有指数补偿的断路器,因为ADO.NET连接池算法描述了已经有效地提供了这一点。
原因:断路器的目的是停止将呼叫传递给不太可能应对的下游系统,从而:(a)对呼叫者快速失败; (b)保护基础系统免受过多的负载。听起来好像ADO.NET的算法已经实现了这两个目标。
类似地,指数补偿重试策略的目标是防止重试本身“增加”负载(在底层系统上产生自我诱发的DDOS攻击……更多的请求进入,现有的请求也重试)。再一次,这听起来像是ADO.NET的强制退出算法正在强制执行其自己的指数补偿来保护基础数据库,因此在分层自己的Polly指数补偿时可能没有任何好处。最重要的是。
在ADO.NET提供自己的防御的基础上,我很想做一些简单的事情,例如使用重试策略,固定重试间隔为5秒或5余个小巧的秒。 (无论生效的“封锁期”如何,似乎都是5秒的倍数。)
此建议基于以下假设:此ADO.NET连接池管理(就此阻塞时间而言)是所有发生在调用方的;也就是说,嵌入在调用应用程序中的ADO.NET代码正在确定其连接池已得到充分利用,并且在阻塞时段中拒绝了进一步的连接尝试,而没有将网络调用传递给基础SQL服务器进行检查。如果该假设不正确,那么上面的建议(*)可能是错误的,并且您最好使用指数退避重试策略来避免连接重试尝试使数据库服务器超载。
注意事项:我尚未直接使用此特定的ADO.NET限制。那些有更好建议的人。那些对内部ADO.NET体系结构了解得更多的人可能会更好地知道,每隔五秒钟(如我所建议的那样)进行一次尝试(可能被拒绝)是多么“昂贵”。
附录:此讨论还忽略了导致线程/ CPU匮乏或类似情况的调用方内并行需求高的任何方面。如果这是一个问题,请考虑以某个已知的可承受极限为准pro-active load shedding。