Polly - 如何记录最终错误并继续?

PSX*_*XYU 5 c# app-startup serilog polly retry-logic

我正在尝试在 .Net Core 3.1 (Azure Functions v3) 中设置 Polly。

我想在 Startup 类中创建一个策略,我可以将其注入到函数中。

我正在寻找的行为是:它应该等待并重试 3 次 - 如果最后一次尝试失败 - 它应该捕获并记录异常(Serilog),否则继续。

目前我有以下代码:

AsyncRetryPolicy emailRetryPolicy = Policy.Handle<Exception>()
    .WaitAndRetryAsync(3, retryAttempt =>
     TimeSpan.FromMilliseconds(retryAttempt * 500));
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,我错过了 3 次尝试后记录错误的部分 - 然后继续。知道如何做到这一点吗?

Serilog 也添加到 Startup 类中(显示部分代码)

builder.Services.AddLogging(al => al.AddSerilog(logger));
Run Code Online (Sandbox Code Playgroud)

我将使用MailKit发送一封电子邮件,并希望在由于某些原因失败时进行记录。它不应该停止程序的运行。

Pet*_*ala 5

重试策略的工作原理如下:

  • 它尝试执行该操作
    • 如果失败并且策略处理了它,那么它将等待预定义的时间,然后再进行下一次尝试
    • 如果失败并且策略不处理它,那么它将返回原始值(这可能是一个例外)
  • 达到最大重试次数(第一次初始尝试 + n 次重试尝试)后仍然失败,则它将返回原始值

根据您希望使用此重试策略包装的业务逻辑,您有以下两个选项:

  1. 如果它是一个函数,那么您可以使用Fallback 策略。(显然,如果您可以提供回退值。)在回退中,您进行日志记录,然后返回回退值。您可以将这两个策略与 链接起来Policy.WrapAsync,但要注意它们的顺序。

后备策略示例:

var fallbackPolicy = Policy<YourResponse>
    .Handle<Exception>()
    .FallbackAsync( (ct) =>
    {
         logger.LogError("Operation has been failed after several retries ...");
         return Task.FromResult(new YourResponse { ... });
    });
                
var combinedPolicy = Policy.WrapAsync(fallbackPolicy, retryPolicy);
Run Code Online (Sandbox Code Playgroud)
  1. 如果它是一个方法,那么你可以使用onRetryAsync的回调AsyncRetryPolicy

重试策略示例:

var retryPolicy = Policy
    .Handle<Exception>()
    .WaitAndRetryAsync(
        settings.RetryCount,
        _ => TimeSpan.FromMilliseconds(settings.SleepDurationInMilliseconds),
        onRetryAsync: (ex, count, context) =>
            logger.LogError("Operation has been failed after several retries ...");
    );
Run Code Online (Sandbox Code Playgroud)

我想强调的是,重试策略是为幂等操作而设计的。任何可能会发送电子邮件作为副作用的服务调用都不是幂等操作