我们有一家供应商业绩下滑很多。我们不再希望电路在他们向我们传回 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
也做同样的事情。
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)