.net 如何使用Polly过滤重试策略的特定端点

s4chpxco  于 12个月前  发布在  .NET
关注(0)|答案(2)|浏览(61)

如何使用Polly过滤重试策略的特定端点
所有客户端请求MyServiceHttpClient将重试。如何禁用重试策略特定的API?

services.AddHttpClient<MyServiceHttpClient>(client =>
{
    /* configuration */
})
.AddPolicyHandler((serviceProvider, request) => 
    HttpPolicyExtensions.HandleTransientHttpError()
        .WaitAndRetryAsync(3, 
            sleepDurationProvider: retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)), 
            onRetry: (outcome, timespan, retryAttempt, context) =>
            {
                serviceProvider.GetService<ILogger<MyServiceHttpClient>>()
                    .LogWarning("Delaying for {delay}ms, then making retry {retry}.", timespan.TotalMilliseconds, retryAttempt);
            }
            ));

字符串

qoefvg9y

qoefvg9y1#

您可以尝试使用no-op策略:

builder.Services.AddHttpClient<MyServiceHttpClient>(client =>
    {
        /* configuration */
    })
    .AddPolicyHandler((serviceProvider, request) =>
        request.RequestUri.PathAndQuery.StartsWith("/api/") // your predicate
            ? Policy.NoOpAsync<HttpResponseMessage>() // <- no op for matching predicate
            : HttpPolicyExtensions.HandleTransientHttpError()
                .WaitAndRetryAsync(3,
                    sleepDurationProvider: retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)),
                    onRetry: (outcome, timespan, retryAttempt, context) =>
                    {
                        serviceProvider.GetService<ILogger<MyServiceHttpClient>>()
                            .LogWarning("Delaying for {delay}ms, then making retry {retry}.",
                                timespan.TotalMilliseconds, retryAttempt);
                    }
                ));

字符串
或者另一种方法是重复HandleTransientHttpError逻辑,但添加相应的滤波器。

ybzsozfc

ybzsozfc2#

Even though Guru Stron's proposed solution的工作原理是很难维护IMHO。
让我给你一个替代的解决方案。WaitAndRetryAsync有许多不同的重载。有些需要retryCount参数,而有些则不需要。如果使用需要IEnumerable<TimeSpan> retryDurations参数的重载,则可以执行以下操作:

.AddPolicyHandler((serviceProvider, request) =>
    HttpPolicyExtensions.HandleTransientHttpError()
        .WaitAndRetryAsync(
            GetRetryDelays(request), 
            (_, timespan, retryAttempt, __) =>
            {
                //logging               
            }));

字符串
现在让我们看看相关的GetRetryDelays实现

private static readonly Uri DoNotRetryUri = new("https://...");
private const int MaxRetryAttempt = 3;
private static IEnumerable<TimeSpan> GetRetryDelays(HttpRequestMessage request)
{
    if (request.RequestUri == DoNotRetryUri)
        return Array.Empty<TimeSpan>();

    return Enumerable.Range(0, MaxRetryAttempt)
        .Select(retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)))
        .ToArray();
}

  • 如果请求URI与常量相同,则不会执行任何重试
  • 如果请求URI与常量不同,则它将创建一个具有以下值的睡眠持续时间数组
[
   00:00:01
   ,
   00:00:02
   ,
   00:00:04
]

相关问题