Polly C# 在3次指数级重试后,切换为每小时重试一次。

3

我正在尝试使用 Polly 构建一个策略,可以指数级地重试 n 次,然后切换到每小时重试一次。这个能实现吗?

我尝试了 Policy Wrap,但没有得到期望的结果。

2个回答

3
这应该可以通过接受自定义的 sleepDurationProvider 来实现重试。例如,像以下示例一样:
var waitAndRetry = Policy
    .Handle<SomeException>()
    .WaitAndRetry(4, retryAttempt => retryAttempt switch // or WaitAndRetryForever
    {
        <= 3 => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)), // for example n == 3
        _ => TimeSpan.FromHours(1)
    });

1
我可能来晚了,但让我分享一下我的想法:
构建一个可以指数级重试 n 次的策略。以下是一个构建示例:
var retryWithBackoff = Policy
    .Handle<Exception>()
    .WaitAndRetryAsync(Backoff.DecorrelatedJitterBackoffV2(TimeSpan.FromSeconds(1), n));

您需要使用 Polly.Contrib.WaitAndRetry 才能使用 DecorrelatedJitterBackoffV2
在这里(链接),您可以找到一个很好的解释,说明指数退避与抖动是如何工作的。请根据您的需求调整 medianFirstRetryDelay 参数。
同时,请根据您的需要调整触发器。

每隔1小时重试一次。

var retryForeverWithAnHourDelay = Policy
    .Handle<Exception>()
    .WaitAndRetryForeverAsync(_ => TimeSpan.FromHours(1));
  • 我使用了“无限重试”(retry forever),因为根据您的要求,似乎您想一直重试,直到成功为止。
  • 我使用了异步(async)来避免在策略睡眠一个小时时被阻塞。

我尝试了策略包装(policy Wrap)。

var combinedRetryPolicy = Policy.WrapAsync(retryForeverWithAnHourDelay, retryWithBackoff);

请注意顺序:
  • 左侧参数是外部策略
  • 右侧参数是内部策略
换句话说,如果retryWithBackoff失败,则尝试retryForeverWithAnHourDelay
在这里,您可以找到一个简单的Dotnet Fiddle应用程序,演示了它的工作原理:

最后的想法

虽然可以和 Polly 一起睡一个小时,但并不建议这样做。Polly 的重试主要是为了克服短暂的故障。这些故障应该在几分钟内消失/自我修复(而不是在几个小时或几天内)。

如果您需要等待那么长时间,我建议使用某种作业调度程序,如 Quartz.NETHangfire


我已经尝试了策略包装(policy wrap),但没有得到期望的结果。 - eti aggarwal
@etiaggarwal您能否详细说明一下这个问题?期望的结果是什么?观察到了什么? - Peter Csala
使用策略包装代码,重试3次,然后休眠一小时,再次重试3次,如此循环... 我只想在3次重试后更改时间。 - eti aggarwal
@etiaggarwal 你是在谈论你的代码还是我的? - Peter Csala

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接