You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Polly重试策略执行时URL参数重复叠加问题求助

Polly重试策略执行时URL参数重复叠加问题求助

嘿,我最近在使用Polly重试策略时碰到了一个特别诡异的问题,想请各位大佬帮忙分析下原因!

先给大家看下我的Polly策略配置代码:

IAsyncPolicy retryPolicy = Policy
    .Handle<HttpRequestException>(e => !e.IsBadRequest())
    .WaitAndRetryAsync(
        Backoff.DecorrelatedJitterBackoffV2("00:00:01", 5),
        onRetry: (response, timeSpan, retryCount, context) =>
        {
            if (!context.TryGetLogger(out var logger))
            {
                return;
            }
            logger.LogWarning($"Retrying call {retryCount} with timespan: {timeSpan} due to: {response.Message}");
        });

这个策略我是作为单例注入到业务类里使用的,调用方式如下:

var context = new Context($"API-call-{Guid.NewGuid()}", new Dictionary<string, object>
{
    { "logger", _logger },
});

await _resiliencePolicy.ExecuteAsync(async ctx => await _apiClient.Post.Delete(2), context);

问题现象:每当触发重试时,原本的请求URL https://someurl.com/post/2 会变成 https://someurl.com/post/22,而且每多一次重试,末尾的2就会多一个——比如第10次重试时,URL直接变成了https://someurl.com/post/2222222222,完全偏离预期了!

有没有大佬能帮我梳理下这到底是哪里出问题了?感激不尽!


可能的原因分析

大概率问题不在Polly本身,而是你的_apiClient.Post实例存在状态复用的情况:

  • _apiClient.Post这个对象可能维护了内部的请求路径状态,每次调用Delete(2)时,不是基于原始基础URL重新拼接完整路径,而是把参数2追加到了已有的路径后面,导致每次重试都叠加参数。
  • 简单说就是:这个客户端实例不是“无状态”的,第一次调用后它的请求路径已经变成了/post/2,第二次重试调用时又在这个基础上追加了2,就变成了/post/22,以此类推。

解决方案建议

  1. 检查并修复API客户端的实现
    确保Delete方法每次调用都重新构造完整URL,不要依赖实例内部的状态。示例如下:

    // 正确的无状态实现示例
    public class PostClient
    {
        private readonly string _baseUrl;
    
        public PostClient(string baseUrl)
        {
            _baseUrl = baseUrl;
        }
    
        public async Task Delete(int id)
        {
            // 每次调用都重新拼接完整URL,不修改实例状态
            var requestUrl = $"{_baseUrl}/post/{id}";
            // 发送HTTP请求的逻辑...
        }
    }
    
  2. 每次重试使用新的客户端实例
    如果无法修改现有客户端的实现,可以在重试委托里每次创建新的客户端实例,避免状态复用:

    await _resiliencePolicy.ExecuteAsync(async ctx => 
    {
        // 每次重试都初始化一个干净的客户端实例
        var freshApiClient = new ApiClient("https://someurl.com");
        await freshApiClient.Post.Delete(2);
    }, context);
    
  3. 确保委托内的请求逻辑是无状态的
    把构造请求的逻辑完全放在ExecuteAsync的委托中,确保每次重试都执行全新的请求构造流程,而不是复用之前的请求对象或客户端状态。

验证小技巧

你可以先脱离Polly,单独多次调用_apiClient.Post.Delete(2),观察每次的请求URL是否会叠加。如果叠加的话,那就能实锤是客户端的状态问题,和Polly无关——Polly只是忠实地重复执行了你提供的委托逻辑而已。

备注:内容来源于stack exchange,提问作者Ben D

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.20 08:59:36