簡體   English   中英

即使捕獲到異常,Polly 也不會重試

[英]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:觀察到的行為是HttpClientTimeout如何覆蓋所有重試嘗試的方式。


問題的根本原因是HttpClientTimeout被認為是全局超時而不是本地超時:

  • 全局意味着包羅萬象,包括所有的重試嘗試
  • 每次重試的本地均值

如果你想定義本地超時,那么你必須結合重試和超時策略:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM