Polly Http 断路器仅在超时异常时中断

问题描述 投票:0回答:1

我们有一家供应商业绩下滑很多。我们不再希望电路在他们向我们传回 500 个错误等时中断。我们只希望电路在出现超时异常时中断。

IAsyncPolicy<HttpResponseMessage> circuitBreaker = HttpPolicyExtensions
    .HandleTransientHttpError()
    .OrResult(msg => msg.StatusCode == HttpStatusCode.RequestTimeout)
    .AdvancedCircuitBreakerAsync(
        failureThreshold: 0.25,
        samplingDuration: TimeSpan.FromSeconds(300),
        minimumThroughput: 50,
        durationOfBreak: TimeSpan.FromSeconds(20));

services.AddHttpClient<IFinancialDetailsService, FinancialDetailsService>()
        .AddPolicyHandler(circuitBreaker);

我如何通过 Polly 做到这一点?

HandleTransientHttpError
处理 5XX 和 408 错误,但除此之外我没有看到任何其他扩展方法,而
OrTransientHttpError
也做同样的事情。

c# .net dotnet-httpclient polly circuit-breaker
1个回答
0
投票

HandleTransientHttpError
处理 408、5XX 状态代码和
HttpRequestException
。重要的是要了解
HttpClient
不会直接抛出
TimeoutException
。而不是将其包裹在
TaskCanceledException
since .NET 5:

try
{
    var response = await client.GetAsync(downstreamServiceUrl);
}
catch (TaskCanceledException ex) when (ex.InnerException is TimeoutException)
{
   ...
}

对于早期的 .NET 版本,您必须检查

CancellationTokenSource
以确定请求是否已取消或超时。

var cts = new CancellationTokenSource();
try
{
    var response = await client.GetAsync(downstreamServiceUrl, cts.Token);
}
catch (TaskCanceledException ex) when (!cts.IsCancellationRequested)
{
    ...  
}

因此,如果您使用 .NET 5 或更高版本,则必须将以下子句添加到您的策略构建器中(在

.AdvanceCircuitBreakerAsync
之前):

.Or<TaskCanceledException>(ex => ex.InnerException is TimeoutException)

如果您使用的是早期 .NET 版本,则:

.Or<TaskCanceledException>(_ => !cts.IsCancellationRequested)
© www.soinside.com 2019 - 2024. All rights reserved.