![](/img/trans.png)
[英]Polly's CircuitBreakerAsync does not retry if exception occur
[英]Polly does not retry even though an exception is caught
我的 HTTP 服務配置如下:
services
.AddHttpClient<ISomeHttpService, SomeHttpService>((Action<HttpClient>) (client =>
{
client.BaseAddress = new Uri(configuration.BaseAddress);
client.Timeout = TimeSpan.FromSeconds(10);
}))
.AddPolicyHandler(GetPollyPolicy())
.AddHttpMessageHandler<DistributedCachedHttpClientHandler>();
// .....
private static IAsyncPolicy<HttpResponseMessage> GetPollyPolicy()
{
return HttpPolicyExtensions
.HandleTransientHttpError()
.OrInner<Exception>() // I will probably use TimeoutException, for now I'm checking all possible options
.WaitAndRetryAsync(2, _ => TimeSpan.FromMilliseconds(100),
(exception, timeSpan) =>
{
_ = "breakpoint";
});
}
如果SomeHttpService
發出的請求返回 500,它工作得很好。Polly 嘗試再重試 2 次。
但是,如果請求花費的時間超過 10 秒(超過配置的超時),則不會重試。 我什至在 Polly 的操作中設置了一個斷點,我看到在超時發生時命中斷點,但是,當我繼續該程序時。 沒有執行重試,我的 web API 之后直接失敗了 500。
怎么了?
我還嘗試使用Or<Exception>()
而不是OrInner<Exception>()
。
TL;DR:觀察到的行為是HttpClient
的Timeout
如何覆蓋所有重試嘗試的方式。
問題的根本原因是HttpClient
的Timeout
被認為是全局超時而不是本地超時:
如果你想定義本地超時,那么你必須結合重試和超時策略:
var timeoutPolicy = Policy.TimeoutAsync<HttpResponseMessage>(5);
var retryPolicy = HttpPolicyExtensions
.HandleTransientHttpError()
.OrInner<TimeoutRejectedException>()
.WaitAndRetryAsync(2, _ => TimeSpan.FromMilliseconds(10));
var combinedPolicy = Policy.WrapAsync(retryPolicy, timeoutPolicy);
請注意Policy.WrapAsync
的參數順序很重要。
上面的示例定義了每個請求的超時策略(內部)和重試策略(外部),它知道潛在的超時( TimeoutRejectedException
)。
您可以定義兩個超時策略,其中一個在本地起作用,而另一個在全局起作用:
var combinedPolicy = Policy.WrapAsync(globalTimeout, retryPolicy, localTimeout);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.