【问题标题】:Request becomes very slow after 100 rapid requests sent HTTPClient C#发送100个快速请求后请求变得很慢HTTPClient C#
【发布时间】:2021-02-14 12:52:51
【问题描述】:

我使用 HTTPClient(C#、.NET Core 3.1)向不同的主机发送许多请求。

当我的代码发送了 100-200 个请求时,下一个请求开始变得很慢。

我尝试了两种使用 HTTPClient 的方法 - 静态并为每个请求创建新的。我也在测试 HTTPClient 的配置。 我测试了一个任务和更多的请求。

我将每个请求 ConnectionLeaseTimeout 设置为 1、2、3、10 秒。 我尝试将 Timeout 添加到客户端并将 ConnectTimeout 添加到 SocketsHttpHandler。 我添加了处理响应。

我当前的代码:

static async Task<string> Request(string domain)
{
    string result = null;
    string url = $"http://{domain}/";

    var sp = ServicePointManager.FindServicePoint(new Uri(url));
    sp.ConnectionLeaseTimeout = 3 * 1000;

    HttpResponseMessage response = await HttpClient.GetAsync(url);
    try
    {
        result = await response.Content.ReadAsStringAsync();
    }
    catch (Exception ex) when (ex is OperationCanceledException || ex is TaskCanceledException)
    {
        Console.Beep();
    }
    finally
    {
        response.Dispose();
    }

    return result;

}

static void Test()
{
    SocketsHttpHandler socketsHandler = new SocketsHttpHandler
    {
        ConnectTimeout = TimeSpan.FromSeconds(5)
    };
    HttpClient = new HttpClient(socketsHandler);
    LoadDomains("Domains.txt");

    for (int i = 0; i < 50; i++)
    {

        if (Domains.Count != 0)
            Task.Run(async () =>
            {
                ActiveThreads++;
                while (Domains.Count != 0)
                {
                    await Request(Domains.Dequeue());
                    CheckedDomains++;
                }

                ActiveThreads--;
            });

    }
}

static HttpClient HttpClient;

我还注意到套接字没有被重复使用。

@UPDATE 我现在看到有什么东西帮助了我。 我注意到无论我加载 200 或 500 或 1000 个 url,每次在 90% 的请求后它变得非常慢。最后 10% 非常慢。

下一个问题是当我设置Client.DefaultProxy时,每个请求都会变慢。

【问题讨论】:

标签: c# http tcp httpclient


【解决方案1】:

不要将HttpClient 用于多个请求。使用HttpClientFactory 而不是HttpClient

HttpClient有一些问题。

例如:

  1. HttpClient 是一次性的:使用带有 using 语句的 HttpClient 不是最佳选择,因为即使您在 dispose HttpClient对象,底层socket不会立即释放 并可能导致名为“套接字耗尽”的严重问题。

  2. HttpClient 旨在被实例化一次并在应用程序的整个生命周期中重复使用。实例化一个 HttpClient 每个请求的类将耗尽可用套接字的数量 在重载下。该问题将导致 SocketException 错误。 解决该问题的可能方法是基于创建 HttpClient 对象为单例或静态。

  3. 当您将其用作单例或静态对象时可以拥有的HttpClient。在这种情况下,单例或静态 HttpClient 不会 尊重 DNS 更改。

解决上述问题并进行管理 HttpClient 实例更简单,.NET Core 2.1 引入了一个新的 HttpClientFactory

什么是HttpClientFactory:

  1. 为命名和配置逻辑 HttpClient 对象提供一个中心位置。例如,您可以配置一个客户端(服务 预配置为访问特定微服务的代理)。
  2. 通过在 HttpClient 中委托处理程序并实现基于 Polly 的中间件来编写传出中间件的概念 Polly 的弹性政策的优势。
  3. HttpClient 已经有了委派处理程序的概念,这些处理程序可以为传出的 HTTP 请求链接在一起。你注册 HTTP 客户进入工厂,您可以使用 Polly 处理程序来使用 Polly 重试、断路器等策略。
  4. 管理 HttpClientMessageHandlers 的生命周期以避免在管理 HttpClient 时可能出现的上述问题/问题 终其一生。

原答案是这样的:https://stackoverflow.com/a/60113671/8810311

【讨论】:

  • 我看到了这个答案,但我不知道如何实现它。我会再检查一遍。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-06
  • 1970-01-01
  • 2018-08-07
  • 2021-10-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多