一尘不染

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

c#

HttpClientWebAPI客户端的生存期应该是什么?
拥有HttpClient多个通话实例更好吗?

HttpClient像下面的示例所示,创建和处理每个请求的开销是多少(摘自http://www.asp.net/web-
api/overview/web-api-clients/calling-a-web-api-from- a-net-
client):

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);
    }
}

阅读 324

收藏
2020-05-19

共1个答案

一尘不染

HttpClient已被 设计用于多个呼叫
。即使跨多个线程。该HttpClientHandler有打算重新使用在调用凭据和饼干。拥有一个新HttpClient实例需要重新设置所有这些东西。此外,该DefaultRequestHeaders属性包含用于多个调用的属性。必须在每个请求上重置这些值都无法解决问题。

另一个主要优点HttpClient是能够添加HttpMessageHandlers到请求/响应管道中以应用交叉关注点。这些可能用于日志记录,审核,限制,重定向处理,脱机处理,捕获指标。各种各样的事情。如果在每个请求上创建了一个新的HttpClient,则需要在每个请求上设置所有这些消息处理程序,并且还需要以某种方式在这些处理程序的请求之间共享的任何应用程序级状态。

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

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

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

根据互联网上的请求,我看到了一个不同的故事。由于每次必须重新打开请求,因此我看到了40%的性能下降。

我怀疑对HTTPS连接的影响会更糟。

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

2020-05-19