我使用AddHttpClient() 依赖注入将命名的客户端添加到临时服务.有时,当我在服务器上执行netstat -a时,我看到许多连接以TIME_WAIT或CLOSE_WAIT状态打开.我相信这些连接占用了大量资源,其他TCP连接无法运行.这可能吗?有什么办法可以阻止这些情况,并且安全吗?
I use AddHttpClient() dependency injection to add a named client to a transient service. At times, when I execute netstat -a on the server, I see many connections open with TIME_WAIT or CLOSE_WAIT status. I believe that these connections take up so much resource that, other TCP connections are unable to operate. Is this possible? Is there a way to stop these, and is it safe?
public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { ServicePointManager.DefaultConnectionLimit = 200; services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); services.AddHttpClient(FirebaseService.FirebaseServiceClient, ConfigureFirebaseClient); services.AddTransient<FirebaseService>(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { // The default HSTS value is 30 days. You may want to change this for production scenarios, see aka.ms/aspnetcore-hsts. app.UseHsts(); } app.UseHttpsRedirection(); app.UseMvc(); } void ConfigureFirebaseClient(HttpClient client) { var scopes = new string[] { "www.googleapis/auth/firebase.messaging" }; Stream certificateStream = File.OpenRead("firebase-adminsdk.json"); var serviceCredentials = GoogleCredential.FromStream(certificateStream); certificateStream.Close(); var scopedCredentials = serviceCredentials.CreateScoped(scopes); var token = scopedCredentials.UnderlyingCredential.GetAccessTokenForRequestAsync().GetAwaiter().GetResult(); client.SetBearerToken(token); } } public class FirebaseService { public static string FirebaseServiceClient = "FirebaseServiceClient"; private HttpClient _client; private readonly ILogger<FirebaseService> _logger; private readonly string _messagingUrl; public FirebaseService( ILogger<FirebaseService> logger, IHttpClientFactory clientFactory) { _logger = logger; _messagingUrl = "fcm.googleapis/v1/projects/test2/messages:send"; _client = clientFactory.CreateClient(FirebaseServiceClient); } public async Task<string> PostToFirebase(Dictionary<string, string> payload) { HttpResponseMessage result = null; string cont = null; try { var content = JsonConvert.SerializeObject(payload, Formatting.None); var stringContent = new StringContent(content, Encoding.UTF8, "application/json"); result = await _client.PostAsync(_messagingUrl, stringContent); cont = await result.Content.ReadAsStringAsync(); return cont; } finally { result?.Dispose(); } } } public class ValuesController : ControllerBase { private readonly IServiceProvider _serviceProvider; public ValuesController(IServiceProvider serviceProvider) { _serviceProvider = serviceProvider; } [HttpGet] public async Task<IActionResult> Get() { var payload = new Dictionary<string, string>(); List<Task> tasks = new List<Task>(); for (int i = 0; i < 100; i++) { FirebaseService firebaseService = (FirebaseService)_serviceProvider.GetService(typeof(FirebaseService)); var task = firebaseService.PostToFirebase(payload); tasks.Add(task); Console.WriteLine(i); } await Task.WhenAll(tasks.ToArray()); //Console.WriteLine(result); return Ok(); } }推荐答案
我意识到我遇到问题的连接不是源自client.PostAsync().实际上,它们来自IHttpClientFactory的客户端配置"操作中的firebase令牌身份验证请求.这就是为什么当我切换到单例或静态属性时,CreateClient(clientName)不会被多次调用,并且问题消失了的原因.尽管这是清楚地写在文档中的,但我还是错过了. Each time CreateClient is called, a new instance of HttpClient is created and the configuration action is called.
I realized that the connections that I had problems with weren't originating from client.PostAsync(). In fact they were from the firebase token authentication requests in Client Configuration action of IHttpClientFactory. So that's why when I switched to a singleton or a static property, CreateClient(clientName) wasn't called more than once, and the problem was gone. Although this was written in the documentation clearly, I had missed it. Each time CreateClient is called, a new instance of HttpClient is created and the configuration action is called.
更多推荐
Asp.net Core HttpClient具有许多TIME
发布评论