如何为Polly重试策略中的HTTP请求配置指数级超时?
实现指数级请求超时的Polly配置
要实现每次重试时请求超时时间指数级增长,你需要将动态超时策略与重试策略结合,利用Polly的上下文(Context)获取当前重试次数来计算超时时间。以下是修改后的完整代码:
// 动态超时策略:根据重试次数计算指数增长的超时时间 IAsyncPolicy<HttpResponseMessage> dynamicTimeout = Policy.TimeoutAsync<HttpResponseMessage>( (context, cancellationToken) => { // 获取当前重试次数,首次请求重试次数为0 context.TryGetRetryCount(out int retryCount); // 指数增长逻辑:初始5秒,每次重试超时时间翻倍,上限60秒可按需调整 double timeoutSeconds = 5 * Math.Pow(2, retryCount); timeoutSeconds = Math.Min(timeoutSeconds, 60); // 限制最大超时时间 return Task.FromResult(TimeSpan.FromSeconds(timeoutSeconds)); }); // 重试策略保持原有配置(重试间隔仍为10秒) IAsyncPolicy<HttpResponseMessage> retry = HttpPolicyExtensions.HandleTransientHttpError() .Or<TaskCanceledException>() .Or<TimeoutRejectedException>() .OrResult(msg => msg.StatusCode == System.Net.HttpStatusCode.ServiceUnavailable) .OrResult(msg => msg.StatusCode == System.Net.HttpStatusCode.InternalServerError) .WaitAndRetryAsync(12, _ => TimeSpan.FromSeconds(10)); // 注册HttpClient,策略顺序:重试在外,动态超时在内 builder.Services.AddHttpClient( "ApiClient", client => { client.Timeout = TimeSpan.FromSeconds(230); }) // 基础超时需大于最大动态超时 .AddHeaderPropagation() .AddPolicyHandler(Policy.WrapAsync(retry, dynamicTimeout));
关键说明:
- 动态超时计算:通过
context.TryGetRetryCount获取当前重试次数,首次请求重试次数为0,对应初始5秒超时;后续每次重试超时时间翻倍(5→10→20→…),同时通过Math.Min设置上限避免超时过长。 - 策略顺序:保持
Policy.WrapAsync(retry, dynamicTimeout)的顺序,确保每次重试的请求都会应用对应的动态超时策略。 - 基础HttpClient超时:需设置为大于动态超时的最大值(示例中为60秒),避免HttpClient自身的超时先于Polly的超时触发。
内容的提问来源于stack exchange,提问作者Sergey
相关产品推荐
相关产品推荐

