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

C#/.NET多API请求优化咨询:重试与间隔实现方案

.NET调用不稳定API的重试优化方案与示例

核心优化方向

  • 指数退避策略:替代固定递增的间隔,采用指数级增长的等待时间(如1s、2s、4s、8s...),避免短时间内重复请求给API造成压力,同时提升重试成功率
  • 精准重试判断:只对可恢复的错误(如5xx服务器错误、网络超时、连接失败)进行重试,跳过客户端错误(如400参数错误)
  • 请求与客户端复用:RestClient实例全局复用(而非每次创建),减少资源开销;刷新token后需更新请求头实例
  • 异步并发控制:针对500+条请求的场景,改用异步并行处理并限制并发数,提升整体处理效率,同时避免触发API限流机制
  • 精细化日志:记录每次重试的状态、间隔时间和错误信息,便于排查问题

改进后的代码实现

1. 全局复用RestClient

在类级别初始化RestClient,避免每次请求重复创建:

private readonly RestClient _restClient;
private readonly int _maxRetries = 5;
private readonly int _baseRetryDelayMs = 1000; // 基础重试间隔

public YourServiceClass(string basePath)
{
    ServicePointManager.Expect100Continue = true;
    ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
    
    _restClient = new RestClient(basePath);
}

2. 带指数退避的异步重试方法

public async Task<Table_Price[]> GetPriceTableAsync(string sku, string token)
{
    Table_Price[] response = Array.Empty<Table_Price>();
    Exception lastException = null;

    // 每次请求创建独立的RestRequest实例,避免并发下请求头被篡改
    var request = new RestRequest("api/url", Method.Get);
    request.AddQueryParameter("sku", sku);
    request.AddHeader("Authorization", token);
    request.Timeout = -1;

    for (int attempt = 0; attempt < _maxRetries; attempt++)
    {
        try
        {
            response = await _restClient.GetAsync<Table_Price[]>(request);
            return response;
        }
        catch (HttpRequestException ex) when (ex.StatusCode == HttpStatusCode.Unauthorized)
        {
            // 单独处理401:刷新token并更新请求头
            var newToken = await GetTokenAsync(_authRequest);
            request.RemoveHeader("Authorization");
            request.AddHeader("Authorization", $"Bearer {newToken}");
            token = newToken;
            lastException = ex;
        }
        catch (Exception ex) when (IsRetryableException(ex))
        {
            lastException = ex;
            // 指数退避+随机抖动:避免重试风暴
            int delayMs = _baseRetryDelayMs * (int)Math.Pow(2, attempt);
            delayMs = new Random().Next((int)(delayMs * 0.8), (int)(delayMs * 1.2));
            
            // 记录重试日志
            _CFMContext.Insert_LOG_Error(BrasiliaTime(), $"GetPriceTable({sku})", 
                $"Retry {attempt + 1}/{_maxRetries} - Error: {ex.Message}, Waiting {delayMs}ms");
            
            await Task.Delay(delayMs);
        }
        catch (Exception ex)
        {
            // 不可重试的错误直接终止
            lastException = ex;
            break;
        }
    }

    // 所有重试失败,记录最终错误
    _CFMContext.Insert_LOG_Error(BrasiliaTime(), $"GetPriceTable({sku})", 
        $"002 - Failed after {_maxRetries} attempts: {lastException?.Message ?? "Unknown error"}");
    return response;
}

// 判断是否为可重试的异常
private bool IsRetryableException(Exception ex)
{
    if (ex is HttpRequestException httpEx)
    {
        // 5xx服务器错误或无状态码的网络错误
        return httpEx.StatusCode is >= HttpStatusCode.InternalServerError or null;
    }
    // 超时、连接失败等网络异常
    return ex is TaskCanceledException or SocketException or WebException;
}

3. 500+条请求的异步并发处理

用Parallel.ForEachAsync控制并发数,替代同步foreach提升效率:

public async Task ProcessAllRequestsAsync(List<string> skuList, string initialToken)
{
    // 根据API限流规则设置并发数,示例为10
    var options = new ParallelOptions { MaxDegreeOfParallelism = 10 };
    
    await Parallel.ForEachAsync(skuList, options, async (sku, cancellationToken) =>
    {
        try
        {
            var result = await GetPriceTableAsync(sku, initialToken);
            // 处理返回结果逻辑
        }
        catch (Exception ex)
        {
            _CFMContext.Insert_LOG_Error(BrasiliaTime(), $"ProcessSku({sku})", $"Failed: {ex.Message}");
        }
    });
}

关键优化点说明

  • 指数退避+随机抖动:既避免短时间重复请求压垮API,又防止多客户端同时重试引发的"重试风暴"
  • 异步并发处理:相比同步遍历,大幅提升500+条请求的整体处理速度
  • 精准重试判断:跳过客户端错误(如400),避免无效重试浪费资源
  • 请求实例隔离:每次请求创建独立RestRequest,避免并发场景下请求头被篡改

内容的提问来源于stack exchange,提问作者Willian Lopes

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 01:37:24