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

.NET Core中HttpClient并发请求超20次崩溃的优化方案咨询

.NET Core HttpClient并发压测崩溃问题排查与解决

问题场景

在.NET Core中通过依赖注入封装MyHttpService使用HttpClient发起HTTP请求,使用JMeter进行压测时,并发20或50次请求程序即崩溃,抛出远程主机强迫关闭连接的异常。

相关代码

MyHttpService代码

namespace WebApplication1.UComon
{
    public class MyHttpService
    {
        private readonly HttpClient _httpClient;

        public MyHttpService(HttpClient httpClient)
        {
            _httpClient = httpClient;
        }

        public async Task<string> GetExternalData(string url)
        {
            var response = await _httpClient.GetAsync(url);

            if (response.IsSuccessStatusCode)
            {
                return await response.Content.ReadAsStringAsync();
            }
            else
            {
                return null;
            }
        }
    }
}

TestController代码

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using WebApplication1.UComon;

namespace WebApplication1.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class TestController : ControllerBase
    {
        private readonly MyHttpService _httpService;

        public TestController(MyHttpService httpService)
        {
            _httpService = httpService;
        }

        #region 测试httpclient
        [HttpGet, Route("PostHttp")]
        public IActionResult PostHttp()
        {
            string responseBody = "";
            responseBody = _httpService.GetExternalData("https://www.baidu.com/").Result;
            return Ok(responseBody);
        }
        #endregion
    }
}

抛出异常

System.AggregateException HResult=0x80131500
Message=发生一个或多个错误。(发送请求时出错。)
Source=System.Private.CoreLib
StackTrace: 在 System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions) 在 System.Threading.Tasks.Task`1.get_Result()
内部异常 1: HttpRequestException: 发送请求时出错。
内部异常 2: IOException: 无法从传输连接读取数据: 远程主机强迫关闭了一个现有的连接。
内部异常 3: SocketException: 远程主机强迫关闭了一个现有的连接。

解决方案

1. 修复异步代码阻塞问题

控制器的PostHttp方法为同步方法,但调用异步方法时使用.Result阻塞线程,并发场景下会导致线程池耗尽,进而引发连接超时或被远程服务器关闭。将控制器方法改为异步实现:

[HttpGet, Route("PostHttp")]
public async Task<IActionResult> PostHttp()
{
    string responseBody = await _httpService.GetExternalData("https://www.baidu.com/");
    return Ok(responseBody);
}

2. 调整HttpClient连接数限制

默认情况下,HttpClient的MaxConnectionsPerServer值较低(通常为2),并发请求时会导致连接排队,远程服务器可能因超时主动关闭连接。在依赖注入配置时调整该值:

// Program.cs中配置
builder.Services.AddHttpClient<MyHttpService>()
    .ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler
    {
        MaxConnectionsPerServer = 100 // 根据实际并发需求调整
    });

3. 增强异常处理与重试机制

针对远程服务器偶尔断开连接的情况,可添加重试逻辑提升稳定性。例如手动捕获异常并重试:

// 在MyHttpService中添加简单重试逻辑
public async Task<string> GetExternalData(string url, int retryCount = 2)
{
    for (int i = 0; i <= retryCount; i++)
    {
        try
        {
            var response = await _httpClient.GetAsync(url);
            if (response.IsSuccessStatusCode)
            {
                return await response.Content.ReadAsStringAsync();
            }
        }
        catch (SocketException) when (i < retryCount)
        {
            await Task.Delay(100);
            continue;
        }
    }
    return null;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 22:17:38