Resilienza e ripristino di emergenza nel servizio Azure SignalR

La resilienza e il ripristino di emergenza sono un'esigenza comune per i sistemi online. Servizio Azure SignalR offre già una disponibilità del 99,9%, ma è ancora un servizio a livello di area. Quando si verifica un'interruzione a livello di area, l'istanza del servizio non esegue il failover in un'altra area perché è sempre in esecuzione in un'area.

Per il ripristino di emergenza a livello di area, è consigliabile adottare i due approcci seguenti:

  • Abilitare la replica geografica (modo semplice). Questa funzionalità gestisce automaticamente il failover a livello di area. Se abilitata, è presente una sola istanza di Azure SignalR e non vengono introdotte modifiche al codice. Controllare la replica geografica per informazioni dettagliate.
  • Usare più endpoint in Service SDK. L'SDK del servizio supporta più istanze del servizio SignalR e passa automaticamente ad altre istanze quando alcune di esse non sono disponibili. Con questa funzionalità, è possibile eseguire il ripristino quando si verifica un'emergenza, ma è necessario configurare manualmente la topologia di sistema corretta. Si apprenderà come eseguire questa operazione in questo documento.

Architettura a disponibilità elevata per il servizio SignalR

Per garantire la resilienza tra aree per il servizio SignalR, è necessario configurare più istanze del servizio in aree diverse. In questo modo, quando un'area è inattiva è possibile usare le altre come backup. Quando i server app si connettono a più istanze del servizio, esistono due ruoli, primario e secondario. Primary è un'istanza responsabile della ricezione del traffico online, mentre il database secondario funge da istanza di fallback completamente funzionante. Nell'implementazione dell'SDK, la negoziazione restituisce solo gli endpoint primari, quindi i client si connettono solo agli endpoint primari nei casi normali. Tuttavia, quando l'istanza primaria è inattiva, negozia restituisce endpoint secondari in modo che il client possa comunque stabilire connessioni. L'istanza primaria e il server app sono connessi tramite connessioni server normali, ma l'istanza secondaria e il server app sono connessi tramite un tipo speciale di connessione denominato connessione debole. Una caratteristica distintiva di una connessione debole è che non è in grado di accettare il routing della connessione client a causa della posizione dell'istanza secondaria in un'altra area. Il routing di un client a un'altra area non è una scelta ottimale (aumenta la latenza).

Un'istanza del servizio può avere diversi ruoli se connessa a più server app. Una configurazione tipica per lo scenario tra aree consiste nell'avere due o più coppie di istanze del servizio SignalR e server app. All'interno di ogni coppia, il server app e il servizio SignalR si trovano nella stessa area e il servizio SignalR è connesso al server app come ruolo primario. Server app e servizio SignalR sono connessi anche tra le coppie, ma SignalR diventa un ruolo secondario nella connessione al server di un'altra area.

Con questa topologia, un messaggio da un server può comunque essere recapitato a tutti i client perché tutti i server app e le istanze del servizio SignalR sono interconnessi. Tuttavia, quando un client è connesso, instrada al server app nella stessa area per ottenere una latenza di rete ottimale.

Il diagramma seguente illustra tale topologia:

Diagram shows two regions each with an app server and a SignalR service, where each server is associated with the SignalR service in its region as primary and with the service in the other region as secondary.

Configurare più istanze del servizio SignalR

Più istanze del servizio SignalR sono supportate sia nei server app che nei Funzioni di Azure.

Dopo aver creato il servizio SignalR e i server app/Funzioni di Azure in ogni area, è possibile configurare i server app/Funzioni di Azure per connettersi a tutte le istanze del servizio SignalR.

Configurare nei server app

Questa operazione può essere eseguita in due modi.

Tramite configurazione

Si dovrebbe già sapere come impostare il servizio SignalR stringa di connessione tramite variabili di ambiente/impostazioni app/web.cofig, in una voce di configurazione denominata Azure:SignalR:ConnectionString. Se sono presenti più endpoint, si possono impostare in più voci di configurazione, ognuna con il formato seguente:

Azure:SignalR:ConnectionString:<name>:<role>

Nella Connessione ionString è <name> il nome dell'endpoint ed <role> è il relativo ruolo (primario o secondario). Il nome è facoltativo, ma è utile se si vuole personalizzare ulteriormente il comportamento di routing tra più endpoint.

Tramite codice

Se si preferisce archiviare i stringa di connessione altrove, è anche possibile leggerli nel codice e usarli come parametri durante la chiamata AddAzureSignalR() (in ASP.NET Core) o MapAzureSignalR() (in ASP.NET).

Ecco il codice di esempio:

ASP.NET Core:

services.AddSignalR()
        .AddAzureSignalR(options => options.Endpoints = new ServiceEndpoint[]
        {
            new ServiceEndpoint("<connection_string1>", EndpointType.Primary, "region1"),
            new ServiceEndpoint("<connection_string2>", EndpointType.Secondary, "region2"),
        });

ASP.NET:

app.MapAzureSignalR(GetType().FullName, hub,  options => options.Endpoints = new ServiceEndpoint[]
    {
        new ServiceEndpoint("<connection_string1>", EndpointType.Primary, "region1"),
        new ServiceEndpoint("<connection_string2>", EndpointType.Secondary, "region2"),
    };

È possibile configurare più istanze primarie o secondarie. Se sono presenti più istanze primarie e/o secondarie, negotiate restituisce un endpoint nell'ordine seguente:

  1. Se è online almeno un'istanza primaria, restituisce un'istanza primaria casuale online.
  2. Se tutte le istanze primarie sono inattivo, restituire un'istanza online secondaria casuale.

Configurare in Funzioni di Azure

Vedere questo articolo.

Sequenza di failover e procedure consigliate

La configurazione della topologia di sistema è ora appropriata. Ogni volta che un'istanza del servizio SignalR è inattiva, il traffico online viene instradato ad altre istanze. Ecco cosa accade quando un'istanza primaria è inattiva (e viene ripristinata dopo un certo periodo di tempo):

  1. L'istanza del servizio primario è inattiva e tutte le connessioni server in questa istanza vengono disattivate.
  2. Tutti i server connessi a questa istanza lo contrassegnano come offline e negoziano interrompe la restituzione di questo endpoint e iniziano a restituire l'endpoint secondario.
  3. Tutte le connessioni client in questa istanza vengono chiuse, quindi i client si riconnettono. Poiché i server app restituiscono ora l'endpoint secondario, i client si connettono all'istanza secondaria.
  4. L'istanza secondaria gestisce ora tutto il traffico online. Tutti i messaggi dal server ai client possono comunque essere recapitati perché l'istanza secondaria è connessa a tutti i server app. I messaggi dai client al server, tuttavia, vengono indirizzati solo al server app nella stessa area.
  5. Quando l'istanza primaria è ripristinata e di nuovo online, il server app ristabilisce le connessioni all'istanza e la contrassegna come online. Negotiate ora restituisce di nuovo l'endpoint primario in modo che i nuovi client siano connessi al database primario. Ma i client esistenti non vengono eliminati e vengono comunque indirizzati a secondari fino a quando non si disconnettono.

I diagrammi seguenti illustrano come viene effettuato il failover nel servizio SignalR:

Fig.1 Prima del failover Before Failover

Fig.2 Dopo il failover After Failover

Fig.3 Tempo breve dopo il recupero primario Short time after primary recovers

Come si può osservare, normalmente il traffico online (in blu) viene gestito solo dal server app e dal servizio SignalR primari. Dopo il failover, diventano attivi anche il server app e il servizio SignalR secondari. Quando il servizio SignalR primario è di nuovo online, i nuovi client si connetteranno al servizio SignalR primario. I client esistenti restano invece connessi a quello secondario, quindi il traffico viene gestito da entrambe le istanze. Dopo la disconnessione di tutti i client esistenti, il sistema tornerà alla situazione normale (figura 1).

Per implementare un'architettura a disponibilità elevata tra più aree sono disponibili due modelli principali:

  1. Il primo consiste nell'usare una coppia di server app e istanza del servizio SignalR che gestisce tutto il traffico online e un'altra coppia come backup (modello denominato attivo/passivo, illustrato nella figura 1).
  2. L'altro consiste nell'usare due o più coppie di server app e istanze del servizio SignalR, ognuna delle quali gestisce parte del traffico online e funge da backup per altre coppie (modello denominato attivo/attivo, simile alla figura 3).

Il servizio SignalR può supportare entrambi i modelli. La differenza principale risiede nel modo in cui vengono implementati i server app. Se i server app sono attivi/passivi, anche il servizio SignalR è attivo/passivo (poiché il server app primario restituisce solo l'istanza primaria del servizio SignalR). Se i server app sono attivi/attivi, anche il servizio SignalR è attivo/attivo (poiché tutti i server app restituiscono le proprie istanze di SignalR primarie, in modo che tutti possano ottenere il traffico).

Tenere presente che, indipendentemente dai modelli che si sceglie di usare, è necessario connettere ogni istanza del servizio SignalR a un server app come primario.

Inoltre, a causa della natura della connessione SignalR (si tratta di una connessione lunga), i client riscontrano interruzioni della connessione quando si verifica un'emergenza e un failover. È necessario gestire tali casi sul lato client per renderlo trasparente ai clienti finali. ad esempio eseguendo la riconnessione dopo la chiusura di una connessione.

Come testare un failover

Seguire la procedura per attivare il failover:

  1. Nella scheda Rete per la risorsa primaria nel portale disabilitare l'accesso alla rete pubblica. Se la risorsa ha la rete privata abilitata, usare le regole di controllo di accesso per negare tutto il traffico.
  2. Riavviare la risorsa primaria.

Passaggi successivi

In questo articolo si è appreso come configurare l'applicazione per ottenere la resilienza per il servizio SignalR. Per altre informazioni dettagliate sulla connessione client/server e il routing di connessione nel servizio SignalR, vedere questo articolo relativo agli elementi interni del servizio SignalR.

Per scenari di ridimensionamento, ad esempio il partizionamento orizzontale che usa più istanze insieme per gestire un numero elevato di connessioni, leggere come ridimensionare più istanze.

Per informazioni dettagliate su come configurare Funzioni di Azure con più istanze del servizio SignalR, leggere il supporto di più istanze di Servizio Azure SignalR in Funzioni di Azure.