SignalRASP.NET Core hospedaje y escalado
Por Andrew Andrew Andrewton-Nurse, Brady Gastery Tom Dykstra
En este artículo se explican las consideraciones de hospedaje y escalado para aplicaciones de tráfico elevado que usan ASP.NET Core SignalR .
Sesiones permanentes
SignalR requiere que el mismo proceso de servidor controle todas las solicitudes HTTP para una conexión específica. Cuando se ejecuta en una granja de servidores (varios servidores), se deben usar SignalR "sesiones permanentes". Algunos equilibradores de carga también denominan "sesiones permanentes" afinidad de sesión. Azure App Service el enrutamiento de solicitudes de aplicación (ARR) para enrutar las solicitudes. Al habilitar la opción "Afinidad de ARR" en el Azure App Service habilitará "sesiones permanentes". Las únicas circunstancias en las que no se requieren sesiones permanentes son:
- Al hospedar en un único servidor, en un único proceso.
- Cuando se usa el servicio de SignalR Azure.
- Cuando todos los clientes están configurados para usar solo WebSockets, y la opción SkipNegotiation está habilitada en la configuración del cliente.
En todas las demás circunstancias (incluso cuando se usa el backplane de Redis), el entorno del servidor debe configurarse para sesiones permanentes.
Para obtener instrucciones sobre cómo configurar Azure App Service SignalR para , vea Publicar una aplicación ASP.NET Core SignalR para Azure App Service . Para obtener instrucciones sobre cómo configurar sesiones permanentes Blazor para aplicaciones que usan el servicio de Azure, SignalR consulte Hospedaje e implementación de ASP.NET Core Blazor Server .
Recursos de conexión TCP
El número de conexiones TCP simultáneas que un servidor web puede admitir es limitado. Los clientes HTTP estándar usan conexiones efímeras. Estas conexiones se pueden cerrar cuando el cliente pasa a estar inactivo y se vuelve a abrir más adelante. Por otro lado, una SignalR conexión es persistente. SignalR las conexiones permanecen abiertas incluso cuando el cliente se queda inactivo. En una aplicación de tráfico elevado que atiende a muchos clientes, estas conexiones persistentes pueden hacer que los servidores alcancen su número máximo de conexiones.
Las conexiones persistentes también consumen algo de memoria adicional para realizar un seguimiento de cada conexión.
El uso pesado de recursos relacionados con la conexión por puede afectar SignalR a otras aplicaciones web hospedadas en el mismo servidor. Cuando SignalR se abre y contiene las últimas conexiones TCP disponibles, otras aplicaciones web del mismo servidor tampoco tienen más conexiones disponibles.
Si un servidor se queda sin conexiones, verá errores de socket aleatorios y errores de restablecimiento de conexión. Por ejemplo:
An attempt was made to access a socket in a way forbidden by its access permissions...
Para evitar que el uso de recursos provoco errores en otras aplicaciones web, ejecute en servidores diferentes SignalR de las SignalR otras aplicaciones web.
Para evitar que el uso de recursos cause errores en una aplicación, escale horizontalmente para limitar el número de conexiones SignalR que un servidor tiene que SignalR controlar.
Escalado horizontal
Una aplicación que usa SignalR debe realizar un seguimiento de todas sus conexiones, lo que crea problemas para una granja de servidores. Agregue un servidor y obtiene nuevas conexiones que los demás servidores no conocen. Por ejemplo, en cada servidor del diagrama siguiente no es consciente de las SignalR conexiones en los demás servidores. Cuando en uno de los servidores desea enviar un mensaje a todos los clientes, el mensaje solo va a los SignalR clientes conectados a ese servidor.

Las opciones para resolver este problema son el backplane de Azure SignalR Service y Redis.
Azure SignalR Service
El servicio de Azure funciona como proxy para el tráfico en tiempo real y se duplica como un backplane cuando la aplicación se escala SignalR horizontalmente en varios servidores. Cada vez que un cliente inicia una conexión al servidor, se redirige al cliente para conectarse al servicio. El proceso se ilustra en el diagrama siguiente:

El resultado es que el servicio administra todas las conexiones de cliente, mientras que cada servidor solo necesita un número constante pequeño de conexiones al servicio, como se muestra en el diagrama siguiente:

Este enfoque de escalado horizontal tiene varias ventajas con respecto a la alternativa del backplane de Redis:
- Las sesiones permanentes, también conocidas como afinidad decliente, no son necesarias, ya que los clientes se redirigen inmediatamente al servicio de Azure SignalR cuando se conectan.
- Una aplicación se puede escalar horizontalmente en función del número de mensajes enviados, mientras que el servicio de Azure se SignalR escala para controlar cualquier número de SignalR conexiones. Por ejemplo, podría haber miles de clientes, pero si solo se envían algunos mensajes por segundo, la aplicación no tendrá que escalar horizontalmente a varios servidores solo para controlar las propias SignalR conexiones.
- Una SignalR aplicación no usará significativamente más recursos de conexión que una aplicación web sin SignalR .
Por estos motivos, se recomienda el servicio de Azure para todas las aplicaciones ASP.NET Core hospedadas en Azure, incluidos App Service, máquinas virtuales SignalR SignalR y contenedores.
Para más información, consulte la documentación del servicio SignalR de Azure.
Backplane de Redis
Redis es un almacén de clave-valor en memoria que admite un sistema de mensajería con un modelo de publicación/suscripción. El SignalR backplane de Redis usa la característica pub/sub para reenviar mensajes a otros servidores. Cuando un cliente realiza una conexión, la información de conexión se pasa al backplane. Cuando un servidor desea enviar un mensaje a todos los clientes, lo envía al backplane. El backplane conoce todos los clientes conectados y los servidores en los que se encuentra. Envía el mensaje a todos los clientes a través de sus respectivos servidores. Este proceso se ilustra en el diagrama siguiente:

El backplane de Redis es el enfoque de escalado horizontal recomendado para las aplicaciones hospedadas en su propia infraestructura. Si hay una latencia de conexión significativa entre el centro de datos y un centro de datos de Azure, es posible que el servicio de Azure no sea una opción práctica para las aplicaciones locales con requisitos de baja latencia o SignalR alto rendimiento.
Las ventajas del servicio de Azure SignalR que se han indicado anteriormente son desventajas para el backplane de Redis:
- Se requieren sesiones permanentes, también conocidas como afinidad decliente, excepto cuando se cumplen las dos condiciones siguientes:
- Todos los clientes están configurados para usar solo WebSockets.
- La configuración SkipNegotiation está habilitada en la configuración del cliente. Una vez que se inicia una conexión en un servidor, la conexión debe permanecer en ese servidor.
- Una SignalR aplicación debe escalar horizontalmente en función del número de clientes, incluso si se envían pocos mensajes.
- Una SignalR aplicación usa significativamente más recursos de conexión que una aplicación web sin SignalR .
Limitaciones de IIS Windows sistema operativo cliente
Windows 10 y Windows 8.x son sistemas operativos cliente. IIS en sistemas operativos cliente tiene un límite de 10 conexiones simultáneas. SignalRLas conexiones de son:
- Transitorio y se vuelve a establecer con frecuencia.
- No se elimina inmediatamente cuando ya no se usa.
Las condiciones anteriores hacen que sea probable que se alcanza el límite de 10 conexiones en un sistema operativo cliente. Cuando se usa un sistema operativo cliente para el desarrollo, se recomienda:
- Evite IIS.
- Use Kestrel o IIS Express como destinos de implementación.
Linux con Nginx
A continuación se incluye la configuración mínima necesaria para habilitar WebSockets, ServerSentEvents y LongPolling para SignalR :
http {
map $http_connection $connection_upgrade {
"~*Upgrade" $http_connection;
default keep-alive;
}
server {
listen 80;
server_name example.com *.example.com;
# Configure the SignalR Endpoint
location /hubroute {
# App server url
proxy_pass http://localhost:5000;
# Configuration for WebSockets
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_cache off;
# WebSockets were implemented after http/1.0
proxy_http_version 1.1;
# Configuration for ServerSentEvents
proxy_buffering off;
# Configuration for LongPolling or if your KeepAliveInterval is longer than 60 seconds
proxy_read_timeout 100s;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
}
Cuando se usan varios servidores back-end, se deben agregar sesiones permanentes para evitar que las conexiones SignalR cambien de servidor al conectarse. Hay varias maneras de agregar sesiones permanentes en Nginx. A continuación se muestran dos enfoques en función de lo que tenga disponible.
Se agrega lo siguiente además de la configuración anterior. En los ejemplos siguientes, backend es el nombre del grupo de servidores.
Con código abierto de Nginx,use para ip_hash enrutar las conexiones a un servidor en función de la dirección IP del cliente:
http {
upstream backend {
# App server 1
server localhost:5000;
# App server 2
server localhost:5002;
ip_hash;
}
}
Con Nginx Plus,use para agregar un a las solicitudes y anclar las solicitudes del sticky usuario a un cookie servidor:
http {
upstream backend {
# App server 1
server localhost:5000;
# App server 2
server localhost:5002;
sticky cookie srv_id expires=max domain=.example.com path=/ httponly;
}
}
Por último, proxy_pass http://localhost:5000 cambie en la sección a server proxy_pass http://backend .
Para obtener más información sobre WebSockets sobre Nginx, vea NGINX como proxy de WebSocket.
Para obtener más información sobre el equilibrio de carga y las sesiones permanentes, vea Equilibrio de carga de NGINX.
Para obtener más información sobre ASP.NET Core con Nginx, consulte el siguiente artículo:
Proveedores de SignalR backplane de terceros
Pasos siguientes
Para obtener más información, vea los siguientes recursos: