使用 Polly 重试来处理较长时间间隔的 HTTP 请求错误是否安全



我试图为我的应用程序实现我自己的WebHooks版本。当用户注册他们的 URL 钩子时(假设其错误的 URL 或不会使用 2XX 代码响应(,我想在自定义指数间隔内重试最多五次,例如 5 分钟、30 分钟、2 小时、4 小时和 16 小时。我已经使用 .NET Polly 库实现了这一点。

我的问题是,

1( 在最坏的情况下,第 5 次重试最多可延长 16 小时是否安全?

2(它是否线程安全(Polly 说只要我的代码是线程安全的,它就是线程安全的(,但我担心的是 16 小时的长间隔。

3( 假设 10 个请求失败,并且所有请求都在自己的时间间隔内重试。因此,越来越多的请求在一段时间后失败,我的服务器线程池是否会变满并且无法接受任何新请求?

4(由于间隔时间长,真的值得像库一样使用Polly还是最好使用CRON作业调度程序?

我的实现细节与 Polly 的官方示例IHttpClientFactory(链接(非常相似或相同。

感谢您的建议。

我强烈建议您深入研究 Polly 源代码,它相对容易阅读。

从示例中,如果您从WaitAndRetryAsync函数开始,您将很快到达AsyncRetryEngine。这包含重试实现,这就是为什么它只是称为ImplementationAsync的方法。如果我们跳转到与等待相关的部分,那么您将在那里找到以下代码段:

if (waitDuration > TimeSpan.Zero)
{
await SystemClock.SleepAsync(waitDuration, cancellationToken).ConfigureAwait(continueOnCapturedContext);
}

如果您查看SystemClock,您会发现SleepSleepAsync字段(方法(定义:

public static Func<TimeSpan, CancellationToken, Task> SleepAsync = 
new Func<TimeSpan, CancellationToken, Task>(Task.Delay);
SystemClock.Sleep = (Action<TimeSpan, CancellationToken>) ((timeSpan, cancellationToken) =>
{
if (!cancellationToken.WaitHandle.WaitOne(timeSpan))
return;
cancellationToken.ThrowIfCancellationRequested();
});

如您所见,如果您调用WaitAndRetryAsync,那么您的策略将调用Task.Delay,这是非阻塞的。如果你调用WaitAndRetry那么你的策略将调用WaitHandleWaitOne,这是阻塞。

因此,如果您长时间使用 WaitAndRetry,那么这将阻塞线程(除非它因某种原因终止(。在 WaitAndRetryAsync 的情况下,线程池将在延迟完成后收到有关完成的通知。


但我仍然建议使用 cron 作业来解决此类问题。

最新更新