HttpClient Instancing Per Service-Endpoint

时间:2015-04-30 20:11:02

标签: c# .net asp.net-web-api dotnet-httpclient

在实例化HttpClient时,一个常见的建议是:

但是,基于on this link,我认为评论意味着另一条规则:

  

HttpClient类实例充当发送HTTP请求的会话。 HttpClient实例是应用于该实例执行的所有请求的设置集合。此外,每个HttpClient实例都使用自己的连接池,将其请求与其他HttpClient实例执行的请求隔离开来。

这让我想知道我是否应该为每个与之交互的服务端点创建一个HttpClient实例。通过“服务端点”,我的意思是一个不同的基地址。以下各项将是一个独特的“服务端点”:

当然,如果我打算使用HttpClient的“BaseAddress”属性,并且如果我正在处理并发调用,那么每个“service-endpoint”需要一个HttpClient实例。

但是,HttpClient允许我明确指定一个绝对地址:

HttpClient client = new HttpClient(...);

client.PostAsJsonAsync("http://foo.net/api/Message/", ...);
client.PostAsJsonAsync("http://bar.com/api/Message/", ...);
client.PostAsJsonAsync("http://wow.gov/api/Message/", ...);
client.PostAsJsonAsync("http://now.com/api/Message/", ...);
client.PostAsJsonAsync("http://mom.org/api/Message/", ...);
client.PostAsJsonAsync("http://dog.com/api/Message/", ...);

上面的代码可以工作,这正是我想要的当前应用程序的构建。但是唠叨的问题仍然存在......如果我将一个HttpClient用于我的应用程序与之通信的所有服务端点,那么我做错了什么?

为什么我真的需要上面引文中提到的“连接池隔离”?

2 个答案:

答案 0 :(得分:2)

  

但是我想知道我是否会影响其内部运作   HttpClient因为我使许多端点共享相同的连接   池。

不,我不认为HttpClient的单个实例会耗尽您的资源,但这实际上取决于您要做多少并发请求。 HttpClient旨在为并发请求提供服务,并且通过使用异步API(XXXAsync),您可以实现这一目标。

我建议不要忘记将ServicePointManager.DefaultConnectionLimit设置为更高的数字,因为它的默认值是2(并发请求)。

此外,如果您认为自己会使用单个实例快速上线,我建议您一如既往地了解应用程序以了解确切的瓶颈。

答案 1 :(得分:1)

我也面临着同样的问题。

我的调查结果如下:

  1. 使用HttpClient的单独实例,即使您需要在请求期间更改其非线程安全设置(DefaultRequestHeaders, BaseAddress)。使用每个实例的那些特定设置来创建单独的实例将是有用且安全的。更多详细信息:HttpClient–Is It Really Thread-Safe?

  2. 好,我创建了HttpClient的特定实例,但是我不想使用BaseAdress。从第1点开始,我需要针对每个唯一的BaseAdress(主机)使用新的HttpClient实例。

    但是,如果我使用HttpClient到多个没有绝对地址BaseAdress的主机的请求该怎么办? 您可以追踪从HttpClientSocketsHttpHanlderHttpConnectionPoolManagerdotnet source code)的调用,并看到它为每个主机创建了单独的'HttpConnectionPool'并将池添加到'ConcurrentDictionary'_pools 。也就是说,无论如何,我们为每个唯一主机都有一个单独的池。 这就是为什么我更愿意为多个主机使用单个HttpClient实例而不使用BaseAdress