Al construir una aplicación con ASP.NET, se utiliza una instancia de la clase HttpClient para hacer una solicitud HTTP. Usar HttpClient puede parecer sencillo. Sin embargo, algunos posibles problemas no se detectan hasta que la aplicación está bajo una carga elevada.
Problemas relacionados con la clase HttpClient original proporcionada en .NET:El inicio de sesión del hipervínculo es visible.
HttpClient, aunque implementa IDisposable, declararlo e instanciarlo en la instrucción using no es una operación preferida, porqueAl liberar un objeto HttpClient, el socket subyacente no lo haceal instanteLanzamiento, lo que puede causar problemas de agotamiento de la cavidad.
El problema no es realmente HttpClient en sí, sino el constructor predeterminado de HttpClient, ya que crea una nueva instancia real de HttpMessageHandler con los problemas de "agotamiento de sockets" y cambios DNS mencionados anteriormente.
Crear HttpClient directamente (uso incorrecto)
Instancia directamente el objeto HttpClient y suma using para garantizar la llamada al método Dispos, el código es el siguiente:
Llama a la interfaz 5 veces, envía una solicitud HTTP usando HttpClient y comprueba la conexión de red con el siguiente comando:
Se puede ver que cuando se libera el HttpClient, la conexión entre el ordenador local y el servidor objetivo esTIME_WAITEn caso de alta concurrencia, el error se informará de la siguiente manera:
No se puede conectar al servidor remoto
System.Net.Sockets.SocketException: Only one usage of each socket address (protocol/network address/port) is normally permitted.
Para preguntas, también puedes consultar a:
Crear un HttpClinet con IHttpClientFactory (uso correcto)
Usando la inyección de dependencias DI, IHttpClientFactory es lo mismo que HttpLinet, que se crea usando IHttpClientFactory.
Añade el servicio al archivo de arranque, el código es el siguiente:
El código del controlador de HomeController es el siguiente:
También usamos HttpClinet para enviar 5 solicitudes a través de la interfaz de llamada, y la máquina solo establece una conexión con el servidor objetivo, y la conexión se reutiliza durante el proceso de solicitud. Como se muestra a continuación:
IHttpClientFactory agrupa instancias HttpMessageHandler creadas en fábrica en un pool para reducir el consumo de recursos. Cuando creas una nueva instancia HttpClient, puedes reutilizar la instancia HttpMessageHandler en el pool si el tiempo de vida no ha expirado.
{ "Lifetime": "Singleton", "ServiceType": "System.Net.Http.IHttpClientFactory", "TypeImplementation": "Microsoft.Extensions.Http.DefaultHttpClientFactory" }, { "Lifetime": "Singleton", "ServiceType": "System.Net.Http.IHttpMessageHandlerFactory", "TypeImplementation": "Microsoft.Extensions.Http.DefaultHttpClientFactory" } IHttpClientFactory se implementa por defecto como DefaultHttpClientFactory, con la dirección del código fuente:El inicio de sesión del hipervínculo es visible.
Al usar IHttpClientFactory en una aplicación habilitada para DI, puedes evitar:
- Resuelve el problema del agotamiento de recursos compartiendo la instancia HttpMessageHandler.
- Resuelve la estadía del DNS pasando periódicamente por las instancias de HttpMessageHandler.
Además, existen otras formas de resolver los problemas anteriores utilizando instancias SocketsHttpHandler de larga duración.
- Crea una instancia de SocketsHttpHandler al iniciar la app y úsala durante todo el ciclo de vida de la app.
- Configura PooledConnectionLifetime al valor adecuado según el tiempo de refresco del DNS.
- Crea una instancia de HttpClient usando el nuevo HttpClient (handler, disposeHandler: false) según sea necesario.
El enfoque anterior resuelve problemas de gestión de recursos de manera similar a IHttpClientFactory.
- SocketsHttpHandler entre las instancias HttpClientConexiones compartidas。 Este compartir evita el agotamiento de los vasos.
- SocketsHttpHandler hace bucles de conexiones basadas en PooledConnectionLifetime para evitar que el DNS se quede obsoleto.
Para más uso y configuración, por favor consulte:
El inicio de sesión del hipervínculo es visible.
El inicio de sesión del hipervínculo es visible.
|