首页 > 解决方案 > 如何仅为设置的特定状态代码设置 Polly Retry

问题描述

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

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

目前我的代码如下(2个部分/选项):

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));

标签: c#http-status-codespolly

解决方案


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

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>()and .OrResult<Sendgrid.Response>())正在配置该构建器,以便Policy<T>使用诸如.WaitAndRetryAsync()or的调用来创建 a RetryAsync()。配置方法不关心您要创建什么类型的策略,因此它们可以用于任何策略类型。


推荐阅读