如何仅为设置的特定 StatusCodes 设置 Polly Retry

How to set Polly Retry for the set specific StatusCodes only

关于类似的问题,我有几个问题: 我正在调用 EmailServer 并使用 Polly Policy 来 WaitAndRetry。但我希望重试仅针对特定超时发生:5xx 和 429(并忽略 4xx 的其余部分)。

如何让它更优雅并且涵盖所有 5xx 可能性(因为下面的 HttpStatusCode 没有涵盖所有 5xx 也没有涵盖 429)?

目前我的代码如下 (2 parts/options):

private readonly HttpStatusCode[] _retryHttpStatusCodesList =
    new[]
    {
        HttpStatusCode.InternalServerError,
        HttpStatusCode.NotImplemented,            
        HttpStatusCode.BadGateway,
        HttpStatusCode.ServiceUnavailable,
        HttpStatusCode.GatewayTimeout,
        HttpStatusCode.HttpVersionNotSupported,
        HttpStatusCode.RequestTimeout,
        HttpStatusCode.Unauthorized,
        HttpStatusCode.RequestEntityTooLarge
    };

选项 1:

   var waitAndRetryPolicy = Policy.Handle<Exception>()
                .OrResult<HttpResponseMessage>(r =>  _retryHttpStatusCodesList.Contains(r.StatusCode))
                .RetryAsync(2, (ex, retryCount) => { Console.WriteLine($"Retry count {retryCount}"); });

选项 2(我根本不知道如何检查 StatusCode):

var waitAndRetryPolicy = Policy.Handle<Exception>()
            .WaitAndRetryAsync(_maxRetries, retryAttempt => TimeSpan.FromMinutes(Math.Pow(_waitMinutes, retryAttempt)), 
            (ex, timeSpan) => 
            { 
                Console.WriteLine($"Log Error {ex}"); 
            });

   SendGridClient client = new SendGridClient ();
   var response = await policy.ExecuteAsync (() => 
               client.SendEmailAsync(new SendGridMessage));

您可以直接检查响应代码而不是字典:

var retryPolicy = Policy
    .Handle<Exception>()
    .OrResult<Sendgrid.Response>(r =>
    {
        var statusCode = (int)r.StatusCode;
        return (statusCode >= 500 && statusCode <= 599) || statusCode == 429;
    })
    .RetryAsync(2, (ex, retryCount) => { Console.WriteLine($"Retry count {retryCount}"); });

为了回答您的评论,您只需将对 RetryAsync(...) 的调用替换为 WaitAndRetryAsync(...):

的代码
var waitAndRetryPolicy = Policy
    .Handle<Exception>()
    .OrResult<Sendgrid.Response>(r =>
    {
        var statusCode = (int)r.StatusCode;
        return (statusCode >= 500 && statusCode <= 599) || statusCode == 429;
    })
    .WaitAndRetryAsync(_maxRetries, retryAttempt => TimeSpan.FromMinutes(Math.Pow(_waitMinutes, retryAttempt)),
        (ex, timeSpan) =>
        {
            Console.WriteLine($"Log Error {ex}");
        });

请记住,Polly 是一位流利的政策制定者。这意味着您正在调用的 PolicyBuilder<T> 实例上的方法(例如 .Handle<Exception>().OrResult<Sendgrid.Response>())正在配置该构建器,以便通过调用创建 Policy<T> .WaitAndRetryAsync()RetryAsync()。配置方法不关心您要创建什么类型的策略,因此它们可用于 任何 策略类型。