Este artigo é um artigo espelhado de tradução automática, por favor clique aqui para ir para o artigo original.

Vista: 6079|Resposta: 4

[Fonte] Usar o HttpClient de forma incorreta pode quebrar seu software

[Copiar link]
Publicado em 14/05/2022 17:11:56 | | | |
Tenho usado o HttpClient de forma incorreta por anos, mas eventualmente o pesadelo apareceu. Meu site estava instável e meus clientes muito irritados e, com uma solução simples, o desempenho melhorou muito e a instabilidade foi eliminada.



Ao mesmo tempo, melhorei o desempenho da minha aplicação com um uso mais eficiente dos soquetes.

Os microserviços podem ser um problema difícil de lidar. À medida que mais serviços são adicionados e aplicações monolíticas são decompostas, tendem a haver cada vez mais caminhos de comunicação entre serviços. Existem muitas opções de comunicação, mas HTTP é uma opção muito popular. Se o microserviço for construído em C# ou em qualquer linguagem .NET, é provável que você já esteja usando o HttpClient.


O problema está

A instrução using é uma característica C# que lida com objetos de uso único. Uma vez que o bloco de uso está completo, o objeto de uso único (neste caso HttpClient) sai do escopo e é descartado. Ligue para o método de descarte e limpe quaisquer recursos que estejam sendo usados. Esse é um padrão muito típico no .NET que usamos para tudo, desde o banco de dados até o gravador de fluxos. Na verdade, qualquer objeto com um recurso externo que precise ser limpo usa essa interface IDisposável.

E você não pode ser culpado por querer envolver isso no uso. Primeiro, é considerado uma boa prática fazer isso. Na verdade, a documentação oficial da Microsoft utiliza:


Em geral, ao usar um objeto IDisposável, ele deve ser declarado e instanciado na instrução usando.
Segundo, todo o código que você pode ter visto...... O início do HttpClient vai indicar para você usar o bloco de instrução usando, incluindo a documentação mais recente ASP.NET próprio site. O mesmo é dito no artigo na Internet.

Mas o HttpClient é diferente. Embora implemente a interface IDisposable, na verdade é um objeto compartilhado. Isso significa que, nos bastidores, ele é reentrante e seguro contra fios. Você deve compartilhar uma instância do HttpClient ao longo da vida útil da sua aplicação, em vez de criar uma nova instância para cada execução. HttpClient, vamos ver por quê.

Veja por si mesmo

Aqui está um programa simples para demonstrar o HttpClient:

Isso será direcionado a  http://aspnetmonsters.comAbra 10 solicitações e faça o GET, nós só imprimimos o código de status, assim sabemos que está funcionando. A saída será:

Espera, tem mais!

Todo trabalho e tudo é certo para o mundo. Exceto que não é. Se tirarmos a ferramenta netstat e olharmos o status do soquete da máquina que a roda, veremos:

C:\code\socket>NETSTAT.EXE
...
  Proto Endereço Local Estado do Endereço Estrangeiro
  TCP 10.211.55.6:12050 waws-prod-bay-017:http TIME_WAIT
  TCP 10.211.55.6:12051 waws-prod-bay-017:http TIME_WAIT
  TCP 10.211.55.6:12053 waws-prod-bay-017:http TIME_WAIT
  TCP 10.211.55.6:12054 waws-prod-bay-017:http TIME_WAIT
  TCP 10.211.55.6:12055 waws-prod-bay-017:http TIME_WAIT
  TCP 10.211.55.6:12056 waws-prod-bay-017:http TIME_WAIT
  TCP 10.211.55.6:12057 waws-prod-bay-017:http TIME_WAIT
  TCP 10.211.55.6:12058 waws-prod-bay-017:http TIME_WAIT
  TCP 10.211.55.6:12059 waws-prod-bay-017:http TIME_WAIT
  TCP 10.211.55.6:12060 waws-prod-bay-017:http TIME_WAIT
  TCP 10.211.55.6:12061 waws-prod-bay-017:http TIME_WAIT
  TCP 10.211.55.6:12062 waws-prod-bay-017:http TIME_WAIT
  TCP 127.0.0.1:1695 SIMONTIMMS742B:1696 ESTABELECIDO
...
Bem, é estranho...... O aplicativo saiu, mas ainda há várias dessas conexões abertas para a máquina Azure que hospeda o site ASP.NET Monsters. Eles estão emTIME_WAITstatus, o que significa que a conexão foi fechada de um lado (o nosso), mas ainda estamos esperando para ver se outros pacotes chegam porque podem ter atrasado em algum lugar da rede. Aqui está um diagrama do status do TCP/IP:



O Windows permanecerá conectado nesse estado por 240 segundos (conforme definido ao definir [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\TcpTimedWaitDelay]). O Windows tem um limite para a rapidez com que você pode abrir um novo socket, então se você ficar sem pools de conexão, pode ver um erro como este:

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.
Procurar no Google vai te dar conselhos ruins sobre como reduzir os timeouts de conexão. Na verdade, ao rodar corretamente em um servidor com HttpClient ou em uma aplicação construída de forma semelhante, reduzir os timeouts pode levar a outras consequências adversas. Precisamos entender o que significa "certo" e resolver o problema subjacente, não mexer com variáveis em nível de máquina.

Conserte isso

Se compartilharmos uma instância de HttpClient, podemos reduzir o desperdício de sockets reutilizando-os:

Note que, para toda a aplicação, temos apenas uma instância compartilhada. O HttpClient ainda funciona como antes (na verdade, um pouco mais rápido por causa do reuso do socket). O Netstat agora mostra apenas:

TCP 10.211.55.6:12254 waws-prod-bay-017:http ESTABELECIDO
Em um cenário de produção, minha contagem de sockets fica em torno de 4000 e atinge o pico em mais de 5000, comprimindo efetivamente os recursos disponíveis no servidor e fazendo o serviço travar. Após a implementação da mudança, o número de soquetes em uso caiu de uma média superior a 4000 para consistentemente menos de 400, tipicamente em torno de 100.

Isso faz parte de um gráfico da nossa ferramenta de monitoramento que mostra o que acontece após implantarmos um número limitado de provas de correção para um número selecionado de microserviços.




Foi dramático. Se você tiver qualquer tipo de carga, precisa ter em mente estas duas coisas:

Faça seu HttpClient estático.
Não descarte ou embale seu uso a menos que esteja explicitamente procurando um comportamento específico (como causar falha no seu serviço). HttpClient


resumo

O problema de exaustão do soquete com o qual estamos lutando há meses desapareceu, e nossos clientes fazem um desfile virtual. Não posso subestimar o quão pouco óbvio esse erro é. Ao longo dos anos, estamos acostumados a lidar com objetos implementados, IDisposable, e muitas ferramentas de refatoração como R# e CodeRush realmente avisam se você não fizer isso. Nesse caso, descartar o HttpClient é a abordagem errada. O HttpClient implementa IDisposable e incentiva comportamentos ruins, o que é lamentável

Original:O login do hiperlink está visível.




Anterior:ASP.NET Core hospeda os modelos In-Process e Out-Of-Process no IIS
Próximo:ASP.NET Core (XV) usa HttpClient para enviar requisições HTTP
 Senhorio| Publicado em 14/05/2022 17:25:22 |
O TIME_WAIT TCP é uma operação normal do protocolo TCP, o que significa que, após a última FIN-ACK ser passada, o cliente aguardará o tempo máximo duplo de vida útil (MSL) para garantir que o TCP remoto receba um reconhecimento de sua solicitação de término de conexão. Por padrão, o MSL é de 2 minutos. Você pode ficar no TIME_WAIT por até 4 minutos, conhecidos como dois MSLs.

https://docs.microsoft.com/en-us ... t-from-netstat.html
Publicado em 14/05/2022 22:35:22 |
Aprenda a aprender
Publicado em 19/05/2022 09:39:05 |
É tudo chinês, mas não consigo entender quando está conectado em frases
 Senhorio| Publicado em 06/11/2023 07:16:05 |
teste
Disclaimer:
Todo software, material de programação ou artigos publicados pela Code Farmer Network são apenas para fins de aprendizado e pesquisa; O conteúdo acima não deve ser usado para fins comerciais ou ilegais, caso contrário, os usuários terão todas as consequências. As informações deste site vêm da Internet, e disputas de direitos autorais não têm nada a ver com este site. Você deve deletar completamente o conteúdo acima do seu computador em até 24 horas após o download. Se você gosta do programa, por favor, apoie um software genuíno, compre o registro e obtenha serviços genuínos melhores. Se houver qualquer infração, por favor, entre em contato conosco por e-mail.

Mail To:help@itsvse.com