首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >重试使用Polly

重试使用Polly
EN

Stack Overflow用户
提问于 2022-04-28 07:13:52
回答 1查看 5.3K关注 0票数 2

这两个重试策略是否表示相同?

代码语言:javascript
复制
Policy
    .Handle<SomeExceptionType>()
    .WaitAndRetry(
        new[]
        {
            TimeSpan.FromMinutes(1),
            TimeSpan.FromMinutes(1),
            TimeSpan.FromMinutes(1)
        });
代码语言:javascript
复制
Policy
    .Handle<SomeExceptionType>()
    .WaitAndRetry(
        3,
        retryAttempt => TimeSpan.FromMinutes(1)
    );
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-04-28 07:49:46

是的,他们也这么做。

这两个代码都定义了一个策略,该策略最多执行4次相同的操作:初始尝试+三次额外尝试。

这两个过载的主要区别如下:

  • 前者用静态 way 定义惩罚。
    • 它预先定义了不同尝试之间的延迟。

  • 后者用dynamic way 定义惩罚。
    • 它可以计算重试将要发生的延迟。

在您的特定示例中,您的第二个备选方案可以定义如下:

代码语言:javascript
复制
Policy
    .Handle<SomeExceptionType>()
    .WaitAndRetry(
        3,
        _ => TimeSpan.FromMinutes(1)
    );

使用丢弃运算符,您将显式声明没有在sleepDurationProvider中使用该参数来计算新的延迟。

为了清晰起见,我在这篇文章中使用了可替换的惩罚、延迟和睡眠术语。

更新#1

这里有两个例子,您可以利用动态惩罚计算。

指数退避+抖动

与其在每次尝试之间等待相同的时间,不如使用越来越大的延迟来给下游系统自我愈合的空间。例如: 2,4,8.

抖动只是一个小的随机数,以避免所有客户端同时发送重试尝试。因此,它能够及时分散/分散客户的重试尝试。

代码语言:javascript
复制
const int maxDelayInMilliseconds = 32 * 1000;
var jitterer = new Random();
Policy
  .Handle<HttpRequestException>()
  .WaitAndRetryForever(
      retryAttempt =>
      {
          var calculatedDelayInMilliseconds = Math.Pow(2, retryAttempt) * 1000;
          var jitterInMilliseconds = jitterer.Next(0, 1000);

          var actualDelay = Math.Min(calculatedDelayInMilliseconds + jitterInMilliseconds, maxDelayInMilliseconds);
          return TimeSpan.FromMilliseconds(actualDelay);
      }
  );

断路器感知重试

如果你使用断路器,以避免淹没下游系统,而它的自我愈合,你可以让你的重试意识到这一点。

默认情况下,所有策略都是独立的,它们彼此不知道。如果您在CB打开时发出重试尝试,那么您将收到一个BrokenCircuitException (因此它缩短了执行)。但是您可以根据CB的状态动态计算延迟,这样就可以跳过这些不必要的重试。

断路器的定义

代码语言:javascript
复制
Policy<HttpResponseMessage>
    .HandleResult(res => res.StatusCode == HttpStatusCode.InternalServerError)
    .CircuitBreakerAsync(3, TimeSpan.FromSeconds(2),
       onBreak: (dr, ts, ctx) => { ctx[SleepDurationKey] = ts; },
       onReset: (ctx) => { ctx[SleepDurationKey] = null; });

重试定义

代码语言:javascript
复制
Policy<HttpResponseMessage>
    .HandleResult(res => res.StatusCode == HttpStatusCode.InternalServerError)
    .Or<BrokenCircuitException>()
    .WaitAndRetryAsync(4,
        sleepDurationProvider: (c, ctx) =>
        {
            if (ctx.ContainsKey(SleepDurationKey))
                return (TimeSpan)ctx[SleepDurationKey];
            return TimeSpan.FromMilliseconds(200);
        });

这个高级用例详细描述了这里

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72039462

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档