小编典典

在 WebAPI 客户端中每次调用创建一个新的 HttpClient 的开销是多少?

all

HttpClientWebAPI 客户端的生命周期应该是多少?多个调用
的一个实例更好吗?HttpClient

创建和处理HttpClient每个请求的开销是多少,如下例所示(取自http://www.asp.net/web-api/overview/web-
api-clients/calling-a-web-api-from-一个网络客户端):

using (var client = new HttpClient())
{
    client.BaseAddress = new Uri("http://localhost:9000/");
    client.DefaultRequestHeaders.Accept.Clear();
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

    // New code:
    HttpResponseMessage response = await client.GetAsync("api/products/1");
    if (response.IsSuccessStatusCode)
    {
        Product product = await response.Content.ReadAsAsync<Product>();
        Console.WriteLine("{0}\t${1}\t{2}", product.Name, product.Price, product.Category);
    }
}

阅读 68

收藏
2022-08-15

共1个答案

小编典典

HttpClient已被 设计用于多次调用 。甚至跨多个线程。HttpClientHandler具有旨在跨调用重复使用的凭据和
Cookie。拥有一个新HttpClient实例需要重新设置所有这些东西。此外,该DefaultRequestHeaders属性包含用于多次调用的属性。必须在每个请求上重置这些值会破坏这一点。

另一个主要好处HttpClient是能够添加HttpMessageHandlers到请求/响应管道中以应用横切关注点。这些可以用于日志记录、审计、节流、重定向处理、离线处理、捕获指标。各种不同的东西。如果在每个请求上创建一个新的
HttpClient,则需要在每个请求上设置所有这些消息处理程序,并且还需要提供在这些处理程序的请求之间共享的任何应用程序级状态。

您使用的功能HttpClient越多,您就越会发现重用现有实例是有意义的。

但是,在我看来,最大的问题是,当一个HttpClient类被释放时,它会释放HttpClientHandler,然后强行关闭由TCP/IP管理的连接池中的连接ServicePointManager。这意味着每个带有新的请求都HttpClient需要重新建立一个新的TCP/IP连接。

根据我的测试,在 LAN 上使用纯 HTTP,性能影响可以忽略不计。我怀疑这是因为有一个底层 TCP keepalive
保持连接打开,即使HttpClientHandler尝试关闭它也是如此。

在通过互联网发出的请求中,我看到了一个不同的故事。由于每次都必须重新打开请求,我看到性能下降了 40%。

我怀疑对HTTPS连接的打击会更糟。

我的建议是为您连接到的每个不同 API 在应用程序的整个生命周期中保留一个 HttpClient 实例。

2022-08-15