c# - Asp.net Core HttpClient 有很多 TIME_WAIT 或 CLOSE_WAIT 连接

标签 c# asp.net-mvc asp.net-core

我使用 AddHttpClient() dependency injection 将命名客户端添加到 transient 服务。有时,当我在服务器上执行 netstat -a 时,我看到许多连接以 TIME_WAITCLOSE_WAIT 状态打开。我相信这些连接占用了太多资源,以至于其他 TCP 连接无法运行。这可能吗?有没有办法阻止这些,它安全吗?

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 https://aka.ms/aspnetcore-hsts.
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseMvc();
    }

    void ConfigureFirebaseClient(HttpClient client)
    {
        var scopes = new string[] { "https://www.googleapis.com/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 = "https://fcm.googleapis.com/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();
    }

}

最佳答案

CLOSE_WAIT - 对方关闭了连接。

TIME_WAIT - 本地端点(您的应用程序)关闭了连接。

两个连接都保持几分钟,以防另一端有一些延迟的数据包。

“我相信这些连接占用了如此多的资源,以至于其他 TCP 连接无法运行。这可能吗?” - 我想不是。他们只是保持一个端口打开。这取决于有多少。如果你有几百个就没问题。

“有没有办法阻止这些,安全吗?” - 我不这么认为。它们都有相同的 PID,因此如果您尝试关闭其中一个,您所有的应用程序都将关闭。

期待更好的答案。

关于c# - Asp.net Core HttpClient 有很多 TIME_WAIT 或 CLOSE_WAIT 连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54931543/

相关文章:

c# - 预测 MongoDb 中字符串的索引键长度

asp.net-core - NLog 未登录所有级别

c# - 发送大型 XML 时 IIS 7.5 崩溃

ajax - 使用 ajax 在 Controller 中调用 Action - 不起作用。 (ASP.Net MVC)

html - 如何使用 MVC4 从 TempData 解释 HTML?

c# - 在 ASP.Net Core 应用程序启动期间运行异步代码

c# - http请求不包含.net core 2.1中createresponse的定义

c# - 如何统一循环播放音频?

c# - json 错误错误的 JSON 转义序列

C#命名空间问题: Must avoid namespace containing any class name overlap?