Clustering di sgcWebSockets — Scalare i server WebSocket su più nodi | Blog eSeGeCe

Clustering di sgcWebSockets — Scalare i server WebSocket su più nodi

· Componenti

Un server WebSocket eseguito in un singolo processo è semplice. Nel momento in cui si mettono due o più istanze del server dietro un bilanciatore di carico, qualcosa si rompe silenziosamente: ogni client si connette esattamente a un nodo, quindi un messaggio pubblicato sul nodo A non raggiunge mai i sottoscrittori che si trovano sul nodo B. Canali, broadcast e Presence diventano tutti semi-ciechi. Questo è il motivo più comune in assoluto per cui i team superano i limiti di una libreria WebSocket e migrano altrove.

Il nuovo componente TsgcWSCluster colma questa lacuna. Collocatelo accanto al vostro server, fate puntare i nodi l'uno verso l'altro, e un evento di pubblicazione o di Presence su un qualsiasi nodo raggiunge i sottoscrittori connessi a ogni nodo, lasciando invariato il vostro codice Publish / canale / Presence esistente. Questo articolo illustra i due motori di backplane, la configurazione e gli esempi Delphi e .NET pronti da incollare.

Due motori di backplane

Il clustering funziona tramite un backplane a cui ogni nodo si connette. Quando un client pubblica su un nodo, quel nodo recapita il messaggio ai propri sottoscrittori locali e lo inoltra al backplane; ogni altro nodo lo riceve e lo distribuisce ai propri sottoscrittori locali. I loop sono evitati contrassegnando ciascun messaggio con l'id del nodo di origine.

Il backplane si sceglie con la proprietà EngineType:

Backplane mesh (infrastruttura zero)

Il motore mesh è il modo più rapido per creare un cluster. Assegnate a ciascun nodo una ClusterPort su cui ascoltare e l'host:port dei suoi peer, quindi eseguite l'Attach del protocollo sgc in modo che il suo pub/sub di canale (e Presence) sia in cluster:

uses
  sgcWebSocket, sgcWebSocket_Protocols, sgcWebSocket_Cluster;

var
  oServer: TsgcWebSocketServer;
  oProtocol: TsgcWSPServer_sgc;
  oCluster: TsgcWSCluster;
begin
  oServer := TsgcWebSocketServer.Create(nil);
  oServer.Port := 8080;

  oProtocol := TsgcWSPServer_sgc.Create(nil);
  oProtocol.Server := oServer;

  oCluster := TsgcWSCluster.Create(nil);
  oCluster.EngineType  := clusterMesh;            // zero-infrastructure backplane
  oCluster.ClusterPort := 5410;                   // this node's mesh listener
  oCluster.Peers.Add('192.168.1.101:5410');       // the other nodes
  oCluster.Peers.Add('192.168.1.102:5410');
  oCluster.Attach(oProtocol);                      // cluster this protocol's pub/sub
  oCluster.Start;

  oServer.Active := True;
end;

Questa è l'intera modifica. Un client connesso a questo nodo può eseguire Publish su un canale e i client sugli altri due nodi lo ricevono, esattamente come se fossero tutti su un unico server. Nessuna sessione sticky richiesta.

Backplane Redis

Per distribuzioni di maggiori dimensioni, cambiate il motore in clusterRedis e fatelo puntare al vostro server Redis. Tutto ciò che sta al di sopra del backplane — canali, Presence, il vostro codice applicativo — resta invariato:

oCluster.EngineType   := clusterRedis;
oCluster.RedisHost    := '127.0.0.1';
oCluster.RedisPort    := 6379;
oCluster.RedisPassword := '';                      // optional
oCluster.RedisChannel := 'sgccluster';             // the Pub/Sub channel
oCluster.Attach(oProtocol);
oCluster.Start;

.NET

L'edizione gestita di sgcWebSockets espone lo stesso componente. Eseguite l'Attach del cluster al protocollo sgc del server e avviatelo — una pubblicazione su un nodo raggiunge i sottoscrittori sugli altri:

var server = new TsgcWSServer { Port = 8080 };
var protocol = new TsgcWSPServer_sgc { Server = server };

var cluster = new TsgcWSCluster {
    EngineType  = ClusterEngineType.Mesh,          // zero-infrastructure backplane
    ClusterPort = 5414,
    Protocol    = protocol
};
cluster.Peers.Add("192.168.1.101:5414");
cluster.Peers.Add("192.168.1.102:5414");
cluster.Start();

server.Active = true;

In questa release l'edizione .NET include il motore mesh; il backplane Redis è disponibile nell'edizione Delphi / C++Builder.

Presence a livello di cluster

Presence — "chi è online in questo canale" — è la funzionalità che soffre di più quando un server scala orizzontalmente, perché ogni nodo vede solo i propri membri. TsgcWSCluster risolve questo problema: eseguite l'Attach del protocollo Presence nello stesso modo in cui collegate il protocollo sgc, e l'elenco dei membri diventa l'unione su tutti i nodi. Gli eventi di ingresso / uscita si propagano a livello di cluster, e un nodo che cade ha i propri membri rimossi automaticamente, così da non mostrare mai membri fantasma.

oCluster.Attach(oPresenceProtocol);   // TsgcWSPServer_Presence
// GetMembers now returns the cluster-wide roster, not just this node's.

Sapere quando il cluster è pronto

Ogni cluster espone la propria connettività così da poter attendere il backplane prima di iniziare a pubblicare, oppure mostrare lo stato di salute dei nodi in una dashboard:

oCluster.OnPeerConnected := procedure(Sender: TObject; const aPeer: string)
begin
  // a peer link came up
end;

if oCluster.Ready then            // at least one peer connected (or no peers configured)
  // ConnectedPeerCount tells you how many links are up

Su .NET gli stessi segnali sono OnPeerConnected / OnPeerDisconnected, la proprietà ConnectedPeerCount e IsReady.

Come si integra con il resto della libreria

Il clustering si colloca al di sotto del codice del vostro protocollo, quindi non cambia nient'altro. Gli stessi Publish, sottoscrizioni ai canali, conferme QoS e API di Presence che già utilizzate continuano a funzionare, ora su ogni nodo. Il motore mesh non richiede alcun servizio esterno, il che rende banale una distribuzione a due o tre nodi; Redis è disponibile per quando si scala più in grande. Una demo a due nodi viene fornita con la libreria (02.WebSocket_Protocols\14.MultiNode_Clustering su Delphi, samples\ClusterDemo su .NET) così da poter osservare un messaggio attraversare i nodi sulla vostra macchina.

Disponibilità

Il clustering multi-nodo è una funzionalità dell'edizione Enterprise e compila da Delphi 7 fino a Delphi 13 (Win32/Win64, Linux64, macOS, Android e iOS) e sull'edizione gestita .NET.

I clienti con un abbonamento attivo possono scaricare la nuova build dall'area clienti. Gli utenti trial possono ottenere l'installer aggiornato all'indirizzo esegece.com/products/websockets/download.

Domande, feedback o aiuto per integrare tutto questo nella vostra distribuzione? Contattateci — riceverete una risposta dalle persone che hanno scritto il codice.