提问人:Rafael 提问时间:8/3/2023 最后编辑:Peter CsalaRafael 更新时间:8/3/2023 访问量:208
如何使用 Polly 筛选重试策略的特定终结点
How to filter specific endpoint for retry policy using Polly
问:
如何使用 Polly 筛选重试策略的特定终结点
所有客户端请求都将重试。如何禁用重试策略特定的 api?MyServiceHttpClient
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);
}
));
答:
1赞
Guru Stron
8/3/2023
#1
您可以尝试使用无操作策略:
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
1赞
Peter Csala
8/3/2023
#2
尽管 Guru Stron 提出的解决方案有效,但恕我直言,维护起来非常困难。
让我向您介绍另一种解决方案。有许多不同的重载。有些需要参数,而另一些则不需要。如果您使用需要参数的重载,则可以执行以下操作: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
]
评论