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

标签 c# asp.net-mvc dotnet-httpclient connection-timeout polly

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

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

我的代码如下所示:

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)));

当我尝试访问“未找到”地址而不包装超时策略时,我已检查重试策略是否有效,并且它工作正常。我还尝试将第 (1) 行与状态代码 HttpStatusCode.RequestTimeout 一起使用,而不是在我的情况下找不到,但它不起作用。

当我使用包装并尝试访问已关闭的服务时,它会在第一次尝试时抛出 Polly.Timeout.TimeoutRejectedException,正如我所期望的那样,但不会再次重试。我想不出一种方法来重试多次,或者为每次重试设置超时,或者只是在请求本身超时而不使用超时策略时。

编辑:进一步阅读后https://cm.engineering/transient-timeouts-and-the-retry-rabbit-hole-net-4-5-f406cebbf194看来我的问题出在策略处理内部,我无权访问 HttpClient 的取消 token 。我假设我可以通过覆盖链接中所示的 sendAsync 方法来修复它。在创建工厂时是否有一种优雅的方式来做同样的事情?

最佳答案

Polly documentation on HttpClientFactory在标记为 applying timeouts 的部分中对此进行了介绍:

You may want the retry policy to retry if any individual try timed out. To do this, make the retry policy handle the TimeoutRejectedException which Polly's timeout policy throws.

所以:

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() 调用;不需要对此进行任何更改。

关于c# - 当http请求超时时重试多次使用polly c#,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61441292/

相关文章:

c# - 为什么C#的HttpClient调用不了这个URL(总是超时)?

c# - 如何在 C# 中访问 Silverlight 对象的附加属性?

javascript - 如何从 WebAPI Controller 使用 javascript 函数发送 JSON(不带引号)

c# - 为继承抽象类的类创建构造函数

asp.net - 不支持同时设置 MappedToType 和 InjectionFactory 的注册

c# - 从 WinRT 中的 UI 调用 HttpClient - 没有任何反应

c# COM 对象 & "The value of ESP was not properly saved across a function call..."

c# - DataAnnotation for Password 的正则表达式

asp.net-mvc - Azure 网站不处理到 '.asp' 文件扩展名的路由

c# - 为什么 System.Net.Http.Headers.HttpResponseHeaders 不可索引?