Подтвердить что ты не робот

Экземпляр HttpClient для конечной точки обслуживания

При создании HttpClient один общий совет:

Однако на основе в этой ссылке Я вижу комментарий, который, я думаю, подразумевает другое правило:

Экземпляр класса HttpClient действует как сеанс для отправки HTTP-запросов. Экземпляр HttpClient представляет собой набор параметров, применяемых ко всем запросам, выполняемым этим экземпляром. Кроме того, каждый экземпляр HttpClient использует свой собственный пул соединений, изолируя его запросы от запросов, выполняемых другими экземплярами HttpClient.

Это заставляет меня задаться вопросом, должен ли я создать один экземпляр HttpClient для каждой конечной точки обслуживания, с которой я взаимодействую. В терминах "service-endpoint" я имею в виду отдельный базовый адрес. Каждое из следующих элементов будет представлять собой "конечную точку обслуживания":

Конечно, если я намереваюсь использовать свойство BaseAddress для HttpClient, и если я имею дело с одновременными вызовами, тогда мне нужно будет иметь один экземпляр 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 для всех конечных точек обслуживания, с которыми связано мое приложение?

Есть ли причина, по которой мне действительно нужна "изоляция пула соединений", упомянутая в приведенной выше цитате?

4b9b3361

Ответ 1

Но я хочу знать, буду ли я компрометировать внутреннюю работу HttpClient, потому что я делаю много конечных точек одинаковым соединением бассейн.

Нет, я не думаю, что один экземпляр HttpClient исчерпает ваши ресурсы, но это действительно зависит от того, сколько одновременных запросов вы будете делать. HttpClient предназначен для обслуживания одновременных запросов и с использованием асинхронного API (XXXAsync), вы можете достичь именно этого.

Я бы посоветовал не забывать устанавливать ServicePointManager.DefaultConnectionLimit на большее число, так как по умолчанию это 2 (параллельные запросы).

Кроме того, если вы считаете, что быстро нажмете на стену с помощью одного экземпляра, я бы предложил, как всегда, профилировать ваше приложение, чтобы понять точное узкое место.

Ответ 2

Я тоже столкнулся с тем же вопросом.

И есть результаты моего расследования:

  1. Используйте отдельные экземпляры HttpClient только в том случае, если вам нужно изменить его не поточно- DefaultRequestHeaders, BaseAddress настройки (DefaultRequestHeaders, BaseAddress) во время запросов. Было бы полезно и безопасно создать отдельные экземпляры с набором этих конкретных настроек для каждого экземпляра. Еще несколько подробностей: HttpClient - действительно ли он потокобезопасен?

  2. Хорошо, я создаю конкретный экземпляр HttpClient, но я не хочу использовать BaseAdress. С пункта 1) мне нужно использовать новый экземпляр HttpClient для каждого уникального BaseAdress (хоста).

    Но что, если я использую HttpClient для запросов к нескольким хостам без BaseAdress по абсолютному адресу? Вы можете преследовать вызовы из HttpClient в SocketsHttpHanlder в HttpConnectionPoolManager (исходный код dotnet) и видеть, что он создает отдельный HttpConnectionPool для каждого хоста и добавляет пул в _urols _ ConcurrentDictionary. Это значит, что у нас есть отдельный пул для каждого уникального хоста. Поэтому я предпочитаю использовать один экземпляр HttpClient для нескольких хостов без использования BaseAdress.