.NET Framework 4.8 HttpClient未充分利用已建立连接问题排查
.NET Framework 4.8长期运行ETL应用连接池未充分利用问题
我用.NET Framework 4.8开发了一个管理ETL流程的控制台应用,通过.NET Standard 2.0类库实现基于HttpClient的HTTP请求,需处理数百万条记录,属于长期运行程序。
请求以并行方式发起,最大并发限制为20。应用启动时,我通过ServicePointManager将单一主机的连接池连接数设为50(默认值为2,易引发连接池耗尽),确保请求不会在已占用的连接上排队。随后遍历记录,将其发送到并发限制为20的TPL Dataflow块,该块通过单例HttpClient的API客户端发起请求:
public static async Task Main(string[] args) { ServicePointManager.DefaultConnectionLimit = 50; ... }
public class MyApiClient { private static HttpClient _httpClient { get; set; } public MyApiClient() { httpClient = new HttpClient(); } public async Task<ReturnedObject> UploadNewDocumentAsync(DocParams docParams, DocData docData) { MultipartFormDataContent content = ConstructMultipartFormDataContent(docParams); HttpContent httpContent = docData.ConvertToHttpContent(); content.Add(httpContent); using (HttpResponseMessage response = await _httpClient.PostAsync("document/upload", content)) { return await HttpResponseReader.ReadResponse<ReturnedObject>(response).ConfigureAwait(false); } } }
使用Sysinternals TCPView.exe查看连接状态:应用启动时建立约50个连接,同时有20个左右活跃,符合预期。但运行约24小时后,TCPView显示仅5个连接在并发收发数据,其余50个已建立连接均空闲。此时请求耗时增加,TaskCanceled异常增多(HttpClient超时设为100秒),性能下降。经第三方API厂商确认,他们未收到大量超时请求,推测请求在少数TCP连接上排队,符合连接池耗尽特征。
通过ServicePointManager查看连接信息:
ServicePoint sp = ServicePointManager.FindServicePoint(myApiService.BasePath, WebRequest.DefaultWebProxy); Console.WriteLine( $"CurrentConnections: {sp.CurrentConnections} " + $"ConnectionLimit: {sp.ConnectionLimit}");
输出为:
CurrentConnections: 50 ConnectionLimit: 50
这验证了所有50个连接均已建立且被允许,但.NET未充分利用。该问题可复现:重启应用后会快速建立50个连接,最多20个活跃,24小时后再次出现相同症状。
请问该行为的成因是什么,还有哪些方法可验证我的假设?
内容的提问来源于stack exchange,提问作者SeanOB
相关产品推荐
相关产品推荐

