【问题标题】:Is it safe to use Polly retry to handle HTTP request errors for longer time intervals使用 Polly 重试处理较长时间间隔的 HTTP 请求错误是否安全
【发布时间】:2020-06-08 17:23:59
【问题描述】:

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

我的问题是,

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

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

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

4) 由于间隔时间长,真的值得使用 Polly 之类的库还是更好地使用 CRON 作业调度程序?

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

谢谢你的建议。

【问题讨论】:

标签: c# multithreading asp.net-core thread-safety polly


【解决方案1】:

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

例如,如果您从WaitAndRetryAsync 函数开始,您很快就会到达AsyncRetryEngine。这包含重试实现,这就是为什么它是唯一称为ImplementationAsync 的方法。如果我们跳转到wait related part,那么您将在那里找到以下代码:

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 的情况下,ThreadPool 将在延迟完成后收到有关完成的通知。


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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-08-20
    • 2020-10-17
    • 2020-08-09
    • 1970-01-01
    • 2012-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多