Время жизни клиента Flurl в ASP.Net Core 2.1 и IHttpClientFactory

Flurl утверждает, что использование одноэлементного клиента является рекомендуемым шаблоном:

HttpClient предназначен для однократного создания экземпляра и повторного использования в течение всего жизненного цикла приложения. Создание нового экземпляра HttpClient для каждого запроса, особенно в серверных приложениях, приведет к исчерпанию количества сокетов, доступных при больших нагрузках. Это приведет к ошибкам SocketException.

Но начиная с Asp.Net Core 2.1 существуют обновленные правила для времени жизни HttpClient в Net Core 2.1 < / а>.

Когда вы используете HttpClientFactory для запроса HttpClient, вы фактически получаете каждый раз новый экземпляр, а это означает, что нам не нужно беспокоиться об изменении его состояния. Этот HttpClient может (или не может) использовать существующий HttpClientHandler из пула и, следовательно, использовать существующее открытое соединение.

Как изменить Flurl для использования IHttpClientFactory под капотом? Должен ли я создать пользовательский Flurl settings.HttpClientFactory и создать там HttpClient через MS IHttpClientFactory?


person Karel Kral    schedule 26.06.2018    source источник
comment
Для ASP .Net 2.1 и Flurl 2.0 невозможно создать экземпляр FlurlClient, как предложил Тодд Меньер.   -  person Rodrigo S. Teixeira    schedule 29.11.2018
comment
@ RodrigoS.Teixeira Это технически правильно, необходимый для этого конструктор был введен во Flurl. Http 2.3.1, выпущенный в апреле прошлого года. Вам что-то мешает обновиться?   -  person Todd Menier    schedule 06.12.2018


Ответы (1)


Во-первых, следует отметить, что новый HttpClientFactory от MS предназначен для использования вместе с ASP.NET Core 2.1 и его встроенным контейнером DI. Если вы не вводите FlurlClients в контроллеры или классы обслуживания, а вместо этого используете Flurl следующим образом:

await url.GetJsonAsync();

тогда это даже не актуально. Вам не следует реализовывать IHttpClientFactory Flurl для использования MS. У него нет надлежащего контекста для использования контейнера DI, и вы в конечном итоге прибегнете к местоположению службы, что является анти-шаблоном. Эти новые функции пула сокетов, которыми вы хотите воспользоваться, фактически работают на более низком уровне: _ 4_. Flurl по умолчанию использует HttpClientHander в качестве обработчика сообщений, но, к счастью, он был переписан в .NET Core 2.1, чтобы по умолчанию отложить всю свою работу на SocketsHttpHandler. Другими словами, если вы используете Flurl в приложении .NET Core 2.1, вы уже получаете все новые возможности управления сокетами, над которыми работает MS.

Если вы явно используете FlurlClient в приложении ASP.NET Core 2.1, как своего рода замену HttpClient, и хотели бы внедрить его в свои классы, используя преимущества того, что MS HttpClientFactory может предложить, Я бы посоветовал настроить HttpClientFactory в ConfigureServices точно так, как предписано MS, и когда вам нужен экземпляр FlurlClient, используйте конструктор, который принимает экземпляр HttpClient. Например, при использовании шаблона типизированных клиентов ваш класс обслуживания может выглядеть следующим образом:

public class MyService
{
    private readonly IFlurlClient _flurlClient;

    public MyService(HttpClient httpClient)
    {
        _flurlClient = new FlurlClient(httpClient);
    }
}
person Todd Menier    schedule 01.07.2018
comment
Извините за некро, этот очень старый ответ, но мне интересно: что DefaultHttpClientFactory может здесь предложить, учитывая, что вы сказали, что Flurl уже делегирует объединение сокетов и обновление DNS-запросов в BCL? Учитывая тяжесть ServiceCollection.AddHttp(), мне не нравится его использовать, если только он не добавляет дополнительных преимуществ Flurl. - person Nick Cox; 15.07.2021
comment
@NickCox Справедливый вопрос. HttpClientFactory Flurl имеет очень узкую цель: он позволяет вам контролировать создание HttpClient и HttpMessageHandler, используемых FlurlClient. Это совсем не касается кеширования экземпляров, повторного использования сокетов и т. Д. Только детали конструкции. Если вы предоставите HttpClient конструктору FlurlClient, как в приведенном выше примере, он вообще не будет использоваться. Он используется только тогда, когда вы этого не делаете, и FlurlClient вызовет его один раз (лениво), когда это необходимо. - person Todd Menier; 16.07.2021