【发布时间】:2021-12-18 18:15:14
【问题描述】:
目前,Polly Retry 策略会独立停用所有失败的请求。因此,如果有 10 个请求失败并且我设置了永远重试策略,那么每次重试发生时它会再发送 10 个请求,并且服务器永远不会恢复。
如何异步传递所有失败的请求,只重试一个请求,重试成功后恢复正常流程?
我不能(不想)使用 Circuit Breaker,因为我的服务是后台工作人员服务,而 Circuit Breaker 会破坏整个后台服务逻辑。
// Current code with only retry policy
var retry = HttpPolicyExtensions.HandleTransientHttpError().WaitAndRetryForeverAsync(retryNo => new TimeSpan(0, retryNo > 3 ? 10 : (retryNo * 2), 0));
builder.Services.AddHttpClient<TestClient>().AddPolicyHandler(retry);
用例:我编写了一个后台服务,并不断抓取一个包含 30000 多个页面的网站。为了防止网站过载,我使用SemaphoreSlim(或 Bulkhead)来限制在某个时间点发送到服务器的请求数。
不过,服务器仍有可能拒绝我的请求。那时,我需要重试只有一个失败的请求单元,服务器再次开始接受我的请求。由于我同时发送多个请求,Polly 正在重试所有失败的请求,这使服务器不满意。
期望:
10 个请求失败 -> 重试 1 个请求(单元成功) -> 如果成功则重新发送剩余的 9 个请求。
【问题讨论】:
-
我不确定我是否理解您在寻找什么。你想分散重试吗?如果是这样,请使用带抖动的指数回退。
-
或者您正在寻找断路器替代方案?请提供更多信息以更好地了解您的问题?
-
@PeterCsala 我已经用正确的用例更新了帖子
-
谢谢,现在我了解了用例。我不明白的是避免使用断路器。 CB 是一种工具,用于检测过载的下游系统并在它试图自我修复时停止泛滥。
-
好的,今天晚些时候我会写一篇文章,详细介绍两个选项:A) 使重试策略 CB 感知 B) 使用队列来存储剩余的工作项