Share via


Introduzione a scale-out in SignalR 1.x

di Patrick Fletcher

Avviso

Questa documentazione non è per la versione più recente di SignalR. Esaminare ASP.NET Core SignalR.

In generale, esistono due modi per ridimensionare un'applicazione Web: aumentare e aumentare la scalabilità.

  • Aumentare le prestazioni significa usare un server più grande (o una macchina virtuale più grande) con più RAM, CPU e così via.
  • La scalabilità orizzontale significa aggiungere altri server per gestire il carico.

Il problema del ridimensionamento è che si raggiunge rapidamente un limite sulle dimensioni del computer. Oltre a questo, è necessario aumentare la scala. Tuttavia, quando si aumenta la scalabilità orizzontale, i client possono essere indirizzati a server diversi. Un client connesso a un server non riceverà messaggi inviati da un altro server.

Screenshot del problema in cui un client si trova quando un server viene ridimensionato è che poiché è connesso a un server non riceverà messaggi inviati da un altro server.

Una soluzione consiste nell'inoltrare messaggi tra server usando un componente denominato backplane. Con un backplane abilitato, ogni istanza dell'applicazione invia messaggi al backplane e il backplane li inoltra alle altre istanze dell'applicazione. In elettronica, un backplane è un gruppo di connettori paralleli. Per analogia, un backplane SignalR connette più server.

Screenshot della soluzione per inoltrare messaggi tra server usando un componente denominato backplane.

SignalR offre attualmente tre backplanes:

  • bus di servizio di Azure. Il bus di servizio è un'infrastruttura di messaggistica che consente ai componenti di inviare messaggi in modo senza problemi.
  • Redis. Redis è un archivio chiave-valore in memoria. Redis supporta un modello di pubblicazione/sottoscrizione ("pub/sub") per l'invio di messaggi.
  • SQL Server. Il backplane SQL Server scrive i messaggi nelle tabelle SQL. Il backplane usa Service Broker per la messaggistica efficiente. Tuttavia, funziona anche se Service Broker non è abilitato.

Se si distribuisce l'applicazione in Azure, è consigliabile usare il backplane bus di servizio di Azure. Se si esegue la distribuzione nella propria server farm, considerare i backplan SQL Server o Redis.

Gli argomenti seguenti contengono esercitazioni dettagliate per ogni backplane:

Implementazione

In SignalR ogni messaggio viene inviato tramite un bus di messaggi. Un bus di messaggi implementa l'interfaccia IMessageBus , che fornisce un'astrazione di pubblicazione/sottoscrizione. Il backplanes funziona sostituendo IMessageBus predefinito con un bus progettato per il backplane. Ad esempio, il bus di messaggio per Redis è RedisMessageBus e usa il meccanismo pub /sub Redis per inviare e ricevere messaggi.

Ogni istanza del server si connette al backplane tramite il bus. Quando viene inviato un messaggio, passa al backplane e il backplane lo invia a ogni server. Quando un server riceve un messaggio dal backplane, inserisce il messaggio nella cache locale. Il server recapita quindi messaggi ai client dalla cache locale.

Per ogni connessione client, lo stato di avanzamento del client nella lettura del flusso di messaggi viene monitorato usando un cursore. Un cursore rappresenta una posizione nel flusso di messaggi. Se un client si disconnette e quindi si riconnette, chiede al bus qualsiasi messaggio che è arrivato dopo il valore del cursore del client. La stessa cosa accade quando una connessione usa il polling lungo. Dopo aver completato una richiesta di polling lungo, il client apre una nuova connessione e chiede messaggi che arrivano dopo il cursore.

Il meccanismo di cursore funziona anche se un client viene instradato a un server diverso sulla riconnessione. Il backplane è consapevole di tutti i server e non importa quale server si connette a un client.

Limitazioni

Usando un backplane, la velocità effettiva massima del messaggio è inferiore rispetto a quando i client parlano direttamente a un singolo nodo server. Questo perché il backplane inoltra ogni messaggio a ogni nodo, quindi il backplane può diventare un collo di bottiglia. Se questa limitazione è un problema dipende dall'applicazione. Ecco ad esempio alcuni scenari tipici di SignalR:

  • Trasmissione server (ad esempio, ticker di magazzino): i backplanes funzionano bene per questo scenario, perché il server controlla la frequenza con cui vengono inviati i messaggi.
  • Client-to-client (ad esempio, chat): in questo scenario, il backplane potrebbe essere un collo di bottiglia se il numero di messaggi viene ridimensionato con il numero di client; ovvero, se la frequenza dei messaggi aumenta proporzionalmente come più client si aggiungono.
  • Tempo reale ad alta frequenza (ad esempio, giochi in tempo reale): un backplane non è consigliato per questo scenario.

Abilitazione della traccia per il scaleout di SignalR

Per abilitare la traccia per i backplanes, aggiungere le sezioni seguenti al file web.config, nell'elemento di configurazione radice:

<configuration>
  <system.diagnostics>
    <sources>
      <source name="SignalR.SqlMessageBus">
        <listeners>
          <add name="SignalR-Bus" />
        </listeners>
      </source>
      <source name="SignalR.ServiceBusMessageBus">
        <listeners>
          <add name="SignalR-Bus" />
        </listeners>
      </source>
      <source name="SignalR.ScaleoutMessageBus">
        <listeners>
          <add name="SignalR-Bus" />
        </listeners>
      </source>
    </sources>
    <switches>
      <add name="SignalRSwitch" value="Verbose" />
      <!-- Off, Critical, Error, Warning, Information, Verbose -->
    </switches>
    <sharedListeners>
      <add name="SignalR-Bus" 
          type="System.Diagnostics.TextWriterTraceListener" 
          initializeData="bus.log.txt" />
    </sharedListeners>
    <trace autoflush="true" />
  </system.diagnostics>
  . . .
</configuration>