当http请求使用polly c#超时时重试多次

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

我本来的意图是在请求本身超时时重试多次,例如当尝试与另一个微服务通信时,该微服务关闭了几秒钟,希望这是暂时的失败。如果有一个更简单的解决方案,那就足够了。我决定使用包装策略手动设置每次重试的超时时间,以期获得相同的结果。

[在这里Use a specific timeout connected to a retrypolicy,我已经看到了一个不使用httpclientfactory的类似解决方案,但它对我不起作用。

我的代码如下:

services.AddHttpClient("retryclient", client =>
{
    client.Timeout = TimeSpan.FromSeconds(100);
}).AddPolicyHandler((servs, request) =>
    Policy.HandleResult<HttpResponseMessage>(r =>
        {
            return r.StatusCode == HttpStatusCode.NotFound; //(1)
        }).
.OrTransiesntHttpError().
WaitAndRetryAsync(5, retryAttempt => TimeSpan.FromSeconds(retryAttempt),
    onRetry: (exception, timespan, retryAttempt, context) =>
        { // using servs to log // });
}).WrapAsync(Policy.TimeoutAsync(1)));

我检查了重试策略,当我尝试访问“未找到”地址而不包装超时策略时,它可以正常工作。我还尝试过使用状态代码为HttpStatusCode.RequestTimeout的第(1)行,而不是在我的情况下找不到该行,但它不起作用。

[当我使用包装并尝试访问已关闭的服务时,它会像我期望的那样在第一次尝试时抛出Polly.Timeout.TimeoutRejectedException,但不会重试。我无法找到一种重试多次的方法,无论是为每次重试设置了超时时间,还是只是在请求本身超时而不使用超时策略时。

编辑:进一步阅读https://cm.engineering/transient-timeouts-and-the-retry-rabbit-hole-net-4-5-f406cebbf194之后,似乎我的问题出在策略处理内部,我无权访问HttpClient的取消令牌。我假设我可以通过重写sendAsync方法来修复它,如链接所示。创建工厂时,有没有一种优雅的方法可以做到这一点?

c# asp.net-mvc connection-timeout polly
1个回答
0
投票

如果任何个人尝试超时,您可能希望重试策略重试。为此,请使重试策略处理Polly的超时策略引发的TimeoutRejectedException

所以:

services.AddHttpClient("retryclient", client => { client.Timeout = TimeSpan.FromSeconds(100); }).AddPolicyHandler((servs, request) => Policy.HandleResult<HttpResponseMessage>(r => { return r.StatusCode == HttpStatusCode.NotFound; //(1) }). .OrTransientHttpError() .Or<TimeoutRejectedException>() // ** ADDED ** .WaitAndRetryAsync(5, retryAttempt => TimeSpan.FromSeconds(retryAttempt), onRetry: (exception, timespan, retryAttempt, context) => { // using servs to log // }); }) .WrapAsync(Policy.TimeoutAsync(1)));

Polly正确地将CancellationToken传递给内部.SendAsync()调用;无需对此进行任何更改。

© www.soinside.com 2019 - 2024. All rights reserved.