using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Net.Http.Json; using System.Net; using Newtonsoft.Json; using Microsoft.AspNetCore.Mvc; using System.Text.Json; using System.Security.Authentication.ExtendedProtection; using Newtonsoft.Json.Linq; using System.Text.Json.Serialization.Metadata; namespace HttpClientStudy.UnitTest.HttpClients { /// /// HttpClient 常见问题测试 /// public class HttpClientQuestTest { private readonly ITestOutputHelper _logger; public HttpClientQuestTest(ITestOutputHelper outputHelper) { _logger = outputHelper; } /// /// 多HttpClient实例问题 /// 1、HttpClient虽然继承了 IDisposable 接口,但它是可以被共享的,且线程安全。Using使用并不能立即释放 /// 2、网络特性:虽然HttpClient客户端断开,但Web服务并不知道,连接依然存在,状态为 “ TIME_WAIT”(继续等待看是否还有延迟的包会传输过来。) /// Windows默认为 240s /// 引发常见问题: /// 1、HttpClient 多实例并存,有很大资源消耗; /// 2、在高并发的情况下,连接来不及释放, socket 被耗尽: 程序异常 /// 3、连带着会出现“各种套接字问题” /// /// 查看问题: /// 程序并发或多次请求后,通过 netstate 查看下 TCP 连接情况:有很多 TIME_WAIT 状态连接;很可能程序异常; /// /// 解决: /// 1、复用HttpClient /// 2、HttpClientFactory /// 3、解决DNS问题可以给HttpClient传参:SocketsHttpHandler /// /// [Fact] public async Task Multi_ClientObject_Test() { for (int i = 0; i < 100; i++) { HttpClient httpClient = new HttpClient(); var responseMessage = await httpClient.GetAsync(TestConfig.WebApiBaseUrl + "/api/account/ping"); responseMessage.EnsureSuccessStatusCode(); } } [Fact] public async Task Multi_ClientObject2_Test() { HttpClient httpClient = new HttpClient() { BaseAddress = new Uri(TestConfig.WebApiBaseUrl) }; for (int i = 0; i < 100; i++) { var responseMessage = await httpClient.GetAsync("/api/account/ping"); responseMessage.EnsureSuccessStatusCode(); } } } }