Polly DecorrelatedJitterBackoffV2 - 如何计算完成所有重试所需的最大时间?

Polly DecorrelatedJitterBackoffV2 - how calculate max time required to complete all retries?

提问人:Alasdair Stark 提问时间:8/17/2023 最后编辑:Peter CsalaAlasdair Stark 更新时间:8/17/2023 访问量:73

问:

我们有一个侦听器,该侦听器从服务总线队列接收消息,然后将正文发送到 API。

我们使用 Polly 在云中实现弹性,即 DecorrelatedJitterBackoffV2 策略。

我们对此策略的担忧是,我们不确定如何计算完成所有重试所需的最长时间,例如,何时设置为 500 毫秒并设置为 3。medianFirstRetryDelayretryCount

这对我们很重要,因为服务总线队列上的消息锁定持续时间。我们希望确保锁定持续时间超过完成所有重试所需的时间。

C# Polly Retry-Logic 指数退避

评论

0赞 Wiktor Zychla 8/17/2023
不确定这是否可能。除了连续停用的延迟外,由于您的 API 调用,网络层也存在延迟。这些不容易衡量,具体取决于哪个客户端(例如 http 客户端或 WCF 客户端),您的延迟可能是任意的(WCF 客户端可以配置为等待数小时而不抛出)
0赞 Alasdair Stark 8/17/2023
是的,会有一些我们无法解释的延迟,但是,我们只是试图了解这个特定的时间尺度是否可以被限制

答:

1赞 Peter Csala 8/17/2023 #1

重试

如果您用于生成睡眠持续时间,那么您可以遍历结果,因为它是DecorrelatedJitterBackoffV2IEnumerable

IEnumerable<TimeSpan> delays = Backoff.DecorrelatedJitterBackoffV2(
    medianFirstRetryDelay: TimeSpan.FromMilliseconds(500),
    retryCount: 3);

foreach (var delay in delay) 
...

请记住,生成的 s 在每个方法调用之间可能会有很大差异。
我已经生成了五倍的序列,我得到了这些
TimeSpan

[
   00:00:00.5042179,
   00:00:00.2196652,
   00:00:00.9364482
]

[
   00:00:00.5060196,
   00:00:00.8691744,
   00:00:00.8905491
]

[
   00:00:00.3786930,
   00:00:01.0092010,
   00:00:00.0805103
]

[
   00:00:00.6507813,
   00:00:00.1045026,
   00:00:00.9623235
]

[
   00:00:00.4164084,
   00:00:00.6975145,
   00:00:01.5628308
]

如果计算每个序列中时间跨度的总和,则结果在 1.5 秒和 2.5 秒(通常)之间变化。delays.Select(t => t.TotalMilliseconds).Sum()

超时

您可以通过对每个操作应用本地超时策略来最大化每个操作的持续时间。

在此上下文中,本地意味着以下内容:

  • 重试和超时策略是链接的
  • 超时是内部的,重试是外部的
  • 重试也会触发TimeoutRejectedException

让我们来算一算

要计算最坏情况,您可以执行以下操作:

  • 正如我们所看到的,在最坏的情况下,延迟加起来为 2.5 秒
    • 为了简单起见,让我们将其四舍五入为 3 秒
  • 如果您有本地超时,那么您就知道每次尝试失败需要多少时间(在最坏的情况下)
    • 由于您设置为 3,这意味着您有 4 次尝试(初始调用和 3 次重试)retryCount

如果将超时设置为 1.5 秒,则表示最坏的情况是在 9 秒内完成(4x 1.5 秒 + 3 秒睡眠)。

当然,如果您在 or 内部执行一些耗时的代码,那么也应该将这些代码添加到您的计算中。onTimeoutonRetry

评论

0赞 Alasdair Stark 8/17/2023
谢谢彼得。对不起,我应该提到我们也有 3 秒的链式超时。是否可以保证最坏的情况是 2.5 秒,或者是否有可能知道?我想我可以迭代延迟并设置一个上限,以确保总时间永远不会超过一定数量。
0赞 Peter Csala 8/17/2023
@AlasdairStark 在这里,我展示了一个如何限制睡眠时间的示例。它可以很容易地改变以限制整体睡眠时间。如果你愿意,我可以在今天晚些时候编辑我的帖子,以包括这个逻辑。
1赞 Alasdair Stark 8/18/2023
谢谢。听起来没有办法对最坏的情况有 100% 的信心,所以如果需要,我会限制持续时间。
1赞 Peter Csala 8/18/2023
@AlasdairStark 在这里,您可以找到时间跨度序列生成的源代码。您可以花几个小时来了解这些值是如何生成的......或者只是简单地盖上它。:)