ASP.NET Core SignalR hosting e scalabilitàASP.NET Core SignalR hosting and scaling

Di Andrew Stanton-Nurse, Brady Gastere Tom DykstraBy Andrew Stanton-Nurse, Brady Gaster, and Tom Dykstra

Questo articolo illustra le considerazioni di hosting e scalabilità per le app con traffico elevato che usano ASP.NET Core SignalR .This article explains hosting and scaling considerations for high-traffic apps that use ASP.NET Core SignalR.

Sessioni permanentiSticky Sessions

SignalR richiede che tutte le richieste HTTP per una connessione specifica siano gestite dallo stesso processo server.SignalR requires that all HTTP requests for a specific connection be handled by the same server process. Quando SignalR è in esecuzione in un server farm (più server), è necessario usare "sessioni permanenti".When SignalR is running on a server farm (multiple servers), "sticky sessions" must be used. Le "sessioni permanenti" sono definite anche affinità di sessione da parte di alcuni bilanciamenti del carico."Sticky sessions" are also called session affinity by some load balancers. Il servizio app Azure usa Application Request Routing (arr) per indirizzare le richieste.Azure App Service uses Application Request Routing (ARR) to route requests. L'abilitazione dell'impostazione "affinità ARR" nel servizio app Azure consentirà di "sessioni permanenti".Enabling the "ARR Affinity" setting in your Azure App Service will enable "sticky sessions". Le uniche circostanze in cui non sono richieste sessioni permanenti sono:The only circumstances in which sticky sessions are not required are:

  1. Quando si esegue l'hosting in un singolo server, in un singolo processo.When hosting on a single server, in a single process.
  2. Quando si usa il SignalR servizio di Azure.When using the Azure SignalR Service.
  3. Quando tutti i client sono configurati in modo da usare solo WebSocket e l' impostazione SkipNegotiation è abilitata nella configurazione client.When all clients are configured to only use WebSockets, and the SkipNegotiation setting is enabled in the client configuration.

In tutti gli altri casi (incluso quando viene usato il backplane Redis), è necessario configurare l'ambiente server per le sessioni permanenti.In all other circumstances (including when the Redis backplane is used), the server environment must be configured for sticky sessions.

Per informazioni sulla configurazione del servizio app Azure per SignalR , vedere Pubblicare un' SignalR app ASP.NET Core in app Azure servizio .For guidance on configuring Azure App Service for SignalR, see Pubblicare un' SignalR app ASP.NET Core in app Azure servizio.

Risorse di connessione TCPTCP connection resources

Il numero di connessioni TCP simultanee che un server Web è in grado di supportare è limitato.The number of concurrent TCP connections that a web server can support is limited. I client HTTP standard utilizzano connessioni temporanee.Standard HTTP clients use ephemeral connections. Queste connessioni possono essere chiuse quando il client diventa inattivo e riaperto in un secondo momento.These connections can be closed when the client goes idle and reopened later. D'altra parte, una SignalR connessione è persistente.On the other hand, a SignalR connection is persistent. SignalR le connessioni resteranno aperte anche quando il client diventa inattivo.SignalR connections stay open even when the client goes idle. In un'app a traffico elevato che serve molti client, queste connessioni permanenti possono provocare il raggiungimento del numero massimo di connessioni da parte dei server.In a high-traffic app that serves many clients, these persistent connections can cause servers to hit their maximum number of connections.

Le connessioni permanenti utilizzano anche una quantità di memoria aggiuntiva per tenere traccia di ogni connessione.Persistent connections also consume some additional memory, to track each connection.

L'utilizzo intensivo delle risorse correlate alla connessione SignalR può influire su altre app Web ospitate nello stesso server.The heavy use of connection-related resources by SignalR can affect other web apps that are hosted on the same server. Quando SignalR si apre e contiene le ultime connessioni TCP disponibili, anche altre app Web nello stesso server non dispongono di altre connessioni disponibili.When SignalR opens and holds the last available TCP connections, other web apps on the same server also have no more connections available to them.

Se un server esaurisce le connessioni, verranno visualizzati gli errori di socket casuali e gli errori di reimpostazione della connessione.If a server runs out of connections, you'll see random socket errors and connection reset errors. Esempio:For example:

An attempt was made to access a socket in a way forbidden by its access permissions...

Per evitare SignalR che l'utilizzo delle risorse causi errori in altre app Web, eseguire SignalR su server diversi rispetto alle altre app Web.To keep SignalR resource usage from causing errors in other web apps, run SignalR on different servers than your other web apps.

Per evitare che SignalR l'utilizzo delle risorse causi errori in un' SignalR app, aumentare il numero di connessioni per limitare il numero di connessioni che un server deve gestire.To keep SignalR resource usage from causing errors in a SignalR app, scale out to limit the number of connections a server has to handle.

Aumentare il numero di istanzeScale out

Un'app che usa SignalR deve tenere traccia di tutte le connessioni, che creano problemi per un server farm.An app that uses SignalR needs to keep track of all its connections, which creates problems for a server farm. Aggiungere un server e ottenere nuove connessioni che gli altri server non conoscono.Add a server, and it gets new connections that the other servers don't know about. Ad esempio, in SignalR ogni server del diagramma seguente non è a conoscenza delle connessioni sugli altri server.For example, SignalR on each server in the following diagram is unaware of the connections on the other servers. Quando SignalR in uno dei server si desidera inviare un messaggio a tutti i client, il messaggio passa solo ai client connessi a tale server.When SignalR on one of the servers wants to send a message to all clients, the message only goes to the clients connected to that server.

Ridimensionamento::: NO-LOC (SignalR)::: senza un backplane

Le opzioni per la risoluzione di questo problema sono il SignalR servizio di Azure e il backplane di redis.The options for solving this problem are the Azure SignalR Service and Redis backplane.

Servizio di Azure SignalRAzure SignalR Service

Il SignalR servizio di Azure è un proxy anziché un backplane.The Azure SignalR Service is a proxy rather than a backplane. Ogni volta che un client avvia una connessione al server, il client viene reindirizzato per connettersi al servizio.Each time a client initiates a connection to the server, the client is redirected to connect to the service. Questo processo è illustrato nel diagramma seguente:That process is illustrated in the following diagram:

Stabilire una connessione al servizio Azure::: NO-LOC (SignalR)::: Service

Il risultato è che il servizio gestisce tutte le connessioni client, mentre per ogni server è necessario solo un piccolo numero costante di connessioni al servizio, come illustrato nel diagramma seguente:The result is that the service manages all of the client connections, while each server needs only a small constant number of connections to the service, as shown in the following diagram:

Client connessi al servizio, server connessi al servizio

Questo approccio per la scalabilità orizzontale presenta diversi vantaggi rispetto all'alternativa del backplane redis:This approach to scale-out has several advantages over the Redis backplane alternative:

  • Le sessioni permanenti, note anche come affinità client, non sono necessarie, perché i client vengono immediatamente reindirizzati al servizio di Azure SignalR quando si connettono.Sticky sessions, also known as client affinity, is not required, because clients are immediately redirected to the Azure SignalR Service when they connect.
  • Un' SignalR app può aumentare la scalabilità orizzontale in base al numero di messaggi inviati, mentre il servizio di Azure viene SignalR ridimensionato per gestire un numero qualsiasi di connessioni.A SignalR app can scale out based on the number of messages sent, while the Azure SignalR Service scales to handle any number of connections. Ad esempio, potrebbero essere presenti migliaia di client, ma se vengono inviati solo pochi messaggi al secondo, l' SignalR app non deve essere scalata in più server solo per gestire le connessioni stesse.For example, there could be thousands of clients, but if only a few messages per second are sent, the SignalR app won't need to scale out to multiple servers just to handle the connections themselves.
  • Un' SignalR app non userà significativamente più risorse di connessione rispetto a un'app Web senza SignalR .A SignalR app won't use significantly more connection resources than a web app without SignalR.

Per questi motivi, è consigliabile usare il SignalR servizio Azure per tutte le SignalR app ASP.NET Core ospitate in Azure, tra cui il servizio app, le macchine virtuali e i contenitori.For these reasons, we recommend the Azure SignalR Service for all ASP.NET Core SignalR apps hosted on Azure, including App Service, VMs, and containers.

Per altre informazioni, vedere la SignalR documentazione dei servizi di Azure.For more information see the Azure SignalR Service documentation.

Backplane RedisRedis backplane

Redis è un archivio chiave-valore in memoria che supporta un sistema di messaggistica con un modello di pubblicazione/sottoscrizione.Redis is an in-memory key-value store that supports a messaging system with a publish/subscribe model. Il SignalR backplane Redis usa la funzionalità di pubblicazione/sottoscrizione per l'invio di messaggi ad altri server.The SignalR Redis backplane uses the pub/sub feature to forward messages to other servers. Quando un client effettua una connessione, le informazioni di connessione vengono passate al backplane.When a client makes a connection, the connection information is passed to the backplane. Quando un server vuole inviare un messaggio a tutti i client, lo invia al backplane.When a server wants to send a message to all clients, it sends to the backplane. Il backplane conosce tutti i client connessi e i server in cui si trovano.The backplane knows all connected clients and which servers they're on. Invia il messaggio a tutti i client tramite i rispettivi server.It sends the message to all clients via their respective servers. Questo processo è illustrato nel diagramma seguente:This process is illustrated in the following diagram:

Backplane Redis, messaggio inviato da un server a tutti i client

Il backplane di redis è l'approccio di scalabilità orizzontale consigliato per le app ospitate nella propria infrastruttura.The Redis backplane is the recommended scale-out approach for apps hosted on your own infrastructure. Se è presente una latenza di connessione significativa tra il data center e un data center di Azure, il SignalR servizio di Azure potrebbe non essere un'opzione pratica per le app locali con requisiti di bassa latenza o velocità effettiva elevata.If there is significant connection latency between your data center and an Azure data center, Azure SignalR Service may not be a practical option for on-premises apps with low latency or high throughput requirements.

I SignalR vantaggi dei servizi di Azure indicati in precedenza sono gli svantaggi per il backplane di redis:The Azure SignalR Service advantages noted earlier are disadvantages for the Redis backplane:

  • Le sessioni permanenti, note anche come affinità client, sono necessarie, tranne quando si verificano entrambe le condizioni seguenti:Sticky sessions, also known as client affinity, is required, except when both of the following are true:
    • Tutti i client sono configurati in modo da usare solo WebSocket.All clients are configured to only use WebSockets.
    • L' impostazione SkipNegotiation è abilitata nella configurazione client.The SkipNegotiation setting is enabled in the client configuration. Una volta avviata una connessione in un server, la connessione deve rimanere nel server.Once a connection is initiated on a server, the connection has to stay on that server.
  • Un' SignalR applicazione deve essere scalata in base al numero di client anche se sono stati inviati pochi messaggi.A SignalR app must scale out based on number of clients even if few messages are being sent.
  • Un' SignalR app usa significativamente più risorse di connessione rispetto a un'app Web senza SignalR .A SignalR app uses significantly more connection resources than a web app without SignalR.

Limitazioni di IIS sul sistema operativo client WindowsIIS limitations on Windows client OS

Windows 10 e Windows 8. x sono sistemi operativi client.Windows 10 and Windows 8.x are client operating systems. IIS nei sistemi operativi client ha un limite di 10 connessioni simultanee.IIS on client operating systems has a limit of 10 concurrent connections. SignalRle connessioni sono:SignalR's connections are:

  • Temporaneo e ristabilito di frequente.Transient and frequently re-established.
  • Non viene eliminato immediatamente quando non viene più utilizzato.Not disposed immediately when no longer used.

Le condizioni precedenti consentono di raggiungere il limite di 10 connessioni in un sistema operativo client.The preceding conditions make it likely to hit the 10 connection limit on a client OS. Quando un sistema operativo client viene usato per lo sviluppo, si consiglia quanto segue:When a client OS is used for development, we recommend:

  • Evitare IIS.Avoid IIS.
  • Usare gheppio o IIS Express come destinazioni di distribuzione.Use Kestrel or IIS Express as deployment targets.

Linux con NginxLinux with Nginx

Impostare le intestazioni e del proxy sul Connection Upgrade seguente per i SignalR WebSocket:Set the proxy's Connection and Upgrade headers to the following for SignalR WebSockets:

proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;

Per altre informazioni, vedere nginx come proxy WebSocket.For more information, see NGINX as a WebSocket Proxy.

Provider backplane di terze parti SignalRThird-party SignalR backplane providers

Passaggi successiviNext steps

Per altre informazioni, vedere le seguenti risorse:For more information, see the following resources: