简体   繁体   中英

HttpClient Instancing Per Service-Endpoint

When instancing an HttpClient, the one common piece of advice is:

However, based on this link I see commentary which I think implies another rule:

The HttpClient class instance acts as a session to send HTTP requests. An HttpClient instance is a collection of settings applied to all requests executed by that instance. In addition, every HttpClient instance uses its own connection pool, isolating its requests from requests executed by other HttpClient instances.

This makes me wonder if I am supposed to create one HttpClient instance for each service-endpoint I interact with. By "service-endpoint", I mean a distinct base address. Each of the following would be a distinct "service-endpoint":

Certainly if I intend on using the "BaseAddress" property of the HttpClient, and if I'm dealing with concurrent calls, then I will need to have one instance of HttpClient per "service-endpoint".

However, HttpClient does allow me to specify an absolute address explicitly:

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/", ...);

The above code works, and it is exactly what I want for the current application I'm building. But the nagging question remains...am I doing something wrong if I use one HttpClient for all service-endpoints my application communicates with?

Is there a reason why I would truly need the "connection pool isolation" that was mentioned in the above quotation?

But I want to know if I will be compromising the inner workings of HttpClient because I'm making many endpoints share the same connection pool.

No, I don't think a single instance of HttpClient will exhaust your resources, but that really depends on how many concurrent requests you'll be making. HttpClient is designed to serve concurrent requests, and by using asynchronous API's such ( XXXAsync ), you can achieve just that.

I would advise not to forget to set ServicePointManager.DefaultConnectionLimit to a higher number, as it's default value is 2 (concurrent requests).

Also, If you think you'll be hitting the wall quickly with a single instance, I'd suggest as always to profile your application to understand the exact bottleneck.

I faced with the same question too.

And there are results of my investigation:

  1. Use separate instances of HttpClient just if you need to change its non thread-safely settings ( DefaultRequestHeaders, BaseAddress ) during requests. It would be useful and safely to create separate instances with set of those specific settings for each instance. Some more details: HttpClient–Is It Really Thread-Safe?

  2. Ok, I create specific instance of HttpClient , but I wan't to use BaseAdress . From point 1) I need to use new HttpClient instance per unique BaseAdress (host).

    But what if I use HttpClient for requests to multiple hosts without BaseAdress by absolute address? You can chase the calls from HttpClient to SocketsHttpHanlder to HttpConnectionPoolManager ( dotnet source code ) and see it creates separate 'HttpConnectionPool' for each host and add the pool to 'ConcurrentDictionary' _pools. That means we have separate pool for each unique host anyway. That's why I prefer to use single HttpClient instance for multiple hosts without BaseAdress usage.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM