Ao construir uma aplicação com ASP.NET, uma instância da classe HttpClient é usada para fazer uma requisição HTTP. Usar o HttpClient pode parecer simples. No entanto, alguns problemas potenciais só são percebidos quando a aplicação está sob grande carga.
Questões relacionadas à classe HttpClient original fornecida no .NET:O login do hiperlink está visível.
HttpClient, ao implementar IDisposable, declará-lo e instancia-lo na instrução using não é uma operação preferida, porqueAo liberar um objeto HttpClient, o socket subjacente não é liberadoinstantaneamentesoltar, que pode causar problemas de exaustão do soquete.
O problema não é realmente o HttpClient em si, mas o construtor padrão do HttpClient, pois ele cria uma nova instância real do HttpMessageHandler com os problemas de "exaustão de socket" e mudanças de DNS mencionados acima.
Criando o HttpClient diretamente (uso incorreto)
Instanciando diretamente o objeto HttpClient e adicionando usando para garantir a chamada ao método Dispose, o código é o seguinte:
Chame a interface 5 vezes, envie uma requisição HTTP usando o HttpClient e verifique a conexão de rede com o seguinte comando:
Você pode ver que, quando o HttpClient é liberado, a conexão entre o computador local e o servidor alvo éTIME_WAITNo caso de alta concorrência, o erro será reportado da seguinte forma:
Não consegui se conectar ao servidor remoto
System.Net.Sockets.SocketException: Only one usage of each socket address (protocol/network address/port) is normally permitted.
Para perguntas, você também pode consultar a:
Crie um HttpClinet com IHttpClientFactory (uso correto)
Usando injeção de dependência DI, IHttpClientFactory é o mesmo que HttpLinet, que é criado usando IHttpClientFactory.
Adicione o serviço ao arquivo Inicial, o código é o seguinte:
O código do controlador do HomeController é o seguinte:
Também usamos o HttpClinet para enviar 5 requisições pela interface de chamada, e a máquina só estabelece uma conexão com o servidor alvo, e a conexão é reutilizada durante o processo de solicitação. Como mostrado abaixo:
O IHttpClientFactory agrupa instâncias HttpMessageHandler criadas em fábrica em um pool para reduzir o consumo de recursos. Quando você cria uma nova instância HttpClient, pode reutilizar a instância HttpMessageHandler no pool se o tempo de vida ainda não tiver expirado.
{ "Vitalícia": "Singleton", "ServiceType": "System.Net.Http.IHttpClientFactory", "TypeImplementation": "Microsoft.Extensions.Http.DefaultHttpClientFactory" }, { "Vitalícia": "Singleton", "ServiceType": "System.Net.Http.IHttpMessageHandlerFactory", "TypeImplementation": "Microsoft.Extensions.Http.DefaultHttpClientFactory" } IHttpClientFactory é implementado por padrão como DefaultHttpClientFactory, com o endereço do código-fonte:O login do hiperlink está visível.
Ao usar o IHttpClientFactory em uma aplicação habilitada para DI, você pode evitar:
- Resolva o problema do esgotamento de recursos compartilhando a instância HttpMessageHandler.
- Resolva o enrolamento do DNS passando periodicamente por instâncias do HttpMessageHandler.
Além disso, existem outras formas de resolver os problemas acima usando instâncias SocketsHttpHandler de longa duração.
- Crie uma instância do SocketsHttpHandler na inicialização do app e use-a durante todo o ciclo de vida do app.
- Configure o PooledConnectionLifetime para o valor apropriado com base no tempo de atualização do DNS.
- Crie uma instância de HttpClient usando o novo HttpClient (handler, disposeHandler: false) conforme necessário.
A abordagem acima resolve problemas de gerenciamento de recursos de forma semelhante ao IHttpClientFactory.
- SocketsHttpHandler entre as instâncias HttpClientConexões compartilhadas。 Esse compartilhamento evita a exaustão do soquete.
- SocketsHttpHandler faz loops de conexões com base no PooledConnectionLifetime para evitar o enrolamento do DNS.
Para mais uso e configuração, consulte a:
O login do hiperlink está visível.
O login do hiperlink está visível.
|