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

.NET应用调用外部API运行一段时间后连接关闭如何解决?

问题根因分析

该报错为.NET Framework下高频调用第三方API的典型问题,常见诱因如下:

  • 端口耗尽:每次请求都新建HttpClient/HttpWebRequest实例,导致本地临时端口被大量占用,处于TIME_WAIT状态的端口无法及时释放,超过阈值后新请求无法建立连接
  • 服务端限流:短时间内大量请求发送至同一API,服务端触发频率限制主动断开连接
  • 协议配置错误:未显式指定兼容的TLS版本,API服务端淘汰旧TLS版本后中途连接被拒绝
  • 连接存活配置不当:未开启TCP保活,服务端主动关闭空闲连接后,后续请求复用已关闭连接触发报错
修复方案

1. 全局复用HttpClient实例(最高优先级)

.NET Framework下HttpClient设计为单例使用,每次新建实例会占用独立端口,需全局仅初始化一次:

// 全局静态初始化,整个应用生命周期只创建一次
private static readonly HttpClient _httpClient = new HttpClient(new HttpClientHandler
{
    KeepAlive = true,
    MaxConnectionsPerServer = 10, // 可根据服务端耐受度调整,不要超过服务端并发限制
})
{
    Timeout = TimeSpan.FromSeconds(30)
};

// 程序入口处配置全局连接规则
static void Main(string[] args)
{
    // 显式指定TLS版本,*如果你的.NET Framework版本低于4.7.2不支持Tls13,仅保留Tls12即可
    ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls13;
    ServicePointManager.DefaultConnectionLimit = 10; // 和上面MaxConnectionsPerServer保持一致
    ServicePointManager.SetTcpKeepAlive(true, 30000, 10000); // 开启TCP保活

    // 后续业务逻辑
}

注意不要在每次请求时都新建HttpClient实例,避免端口泄漏

2. 添加限流与重试机制

针对服务端限流场景,控制请求频率,同时添加重试逻辑应对偶发断连:

// 全局限制最大并发请求数为5,避免并发过高触发服务端限流
private static readonly SemaphoreSlim _semaphore = new SemaphoreSlim(5, 5);

// 通用API请求方法
public async Task<string> CallApiAsync(string apiUrl)
{
    await _semaphore.WaitAsync();
    try
    {
        int retryCount = 0;
        // 连接异常最多重试3次
        while (retryCount < 3)
        {
            try
            {
                var response = await _httpClient.GetAsync(apiUrl);
                response.EnsureSuccessStatusCode();
                return await response.Content.ReadAsStringAsync();
            }
            catch (HttpRequestException ex) when (ex.Message.Contains("The underlying connection was closed"))
            {
                retryCount++;
                if (retryCount == 3) throw;
                // 指数退避等待,每次重试等待时间翻倍
                await Task.Delay(1000 * (int)Math.Pow(2, retryCount));
            }
        }
        return null;
    }
    finally
    {
        _semaphore.Release();
        // 每次请求后固定等待200ms,降低请求频率,可根据服务端限流规则调整
        await Task.Delay(200);
    }
}

3. 旧HttpWebRequest适配方案

如果你仍在使用HttpWebRequest而非HttpClient,添加以下配置:

var request = (HttpWebRequest)WebRequest.Create(apiUrl);
request.KeepAlive = true;
request.ProtocolVersion = HttpVersion.Version11;
request.ServicePoint.ConnectionLimit = 10;
request.ServicePoint.Expect100Continue = false;

4. 分批增量处理

不要一次性处理全部3500条记录,每处理200条记录后暂停10~30秒,释放闲置连接后再处理后续批次。

内容的提问来源于stack exchange,提问作者Dharmendra Kumar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 03:09:02