sgcWebSockets Clustering — WebSocket-servers schalen over meerdere nodes | eSeGeCe Blog

sgcWebSockets Clustering — WebSocket-servers schalen over meerdere nodes

· Componenten

Een WebSocket-server die in één proces draait is eenvoudig. Zodra u twee of meer serverinstanties achter een load balancer plaatst, gaat er stilletjes iets mis: elke client maakt verbinding met precies één node, dus een bericht dat op node A wordt gepubliceerd bereikt nooit de abonnees op node B. Channels, broadcasts en Presence worden allemaal halfblind. Dit is veruit de meest voorkomende reden waarom teams een WebSocket-bibliotheek ontgroeien en naar iets anders overstappen.

De nieuwe component TsgcWSCluster dicht dat gat. Plaats hem naast uw server, laat de nodes naar elkaar wijzen, en een publish- of Presence-gebeurtenis op een willekeurige node bereikt abonnees die met elke node verbonden zijn, zonder dat uw bestaande Publish- / channel- / Presence-code verandert. Deze post behandelt de twee backplane-engines, de configuratie en kant-en-klare voorbeelden in Delphi en .NET.

Twee backplane-engines

Clustering werkt via een backplane waarmee elke node verbinding maakt. Wanneer een client op een node publiceert, levert die node het bericht af aan zijn eigen lokale abonnees en stuurt het door naar de backplane; elke andere node ontvangt het en verspreidt het onder zijn lokale abonnees. Lussen worden voorkomen door elk bericht te voorzien van de id van de oorspronkelijke node.

U kiest de backplane met de eigenschap EngineType:

Mesh-backplane (zonder infrastructuur)

De mesh-engine is de snelste manier om te clusteren. Geef elke node een ClusterPort om op te luisteren en de host:port van zijn peers, en koppel vervolgens met Attach het sgc-protocol zodat de channel-pub/sub (en Presence) geclusterd wordt:

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;

Dat is de hele wijziging. Een client die met deze node verbonden is kan met Publish naar een channel publiceren en clients op de andere twee nodes ontvangen het, precies alsof ze allemaal op één server zaten. Geen sticky sessions vereist.

Redis-backplane

Voor grotere implementaties schakelt u de engine over naar clusterRedis en laat u die naar uw Redis-server wijzen. Alles boven de backplane — channels, Presence, uw applicatiecode — blijft hetzelfde:

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

De managed editie van sgcWebSockets stelt dezelfde component beschikbaar. Koppel het cluster aan het sgc-protocol van de server en start het — een publish op de ene node bereikt abonnees op de andere:

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 deze release levert de .NET-editie de mesh-engine; de Redis-backplane is beschikbaar in de Delphi- / C++Builder-editie.

Clusterbrede Presence

Presence — "wie is er online in dit channel" — is de functie die het meest te lijden heeft wanneer een server uitschaalt, omdat elke node alleen zijn eigen leden ziet. TsgcWSCluster lost dat op: koppel met Attach het Presence-protocol op dezelfde manier als u het sgc-protocol koppelt, en de ledenlijst wordt de vereniging over alle nodes heen. Join- / leave-gebeurtenissen verspreiden zich clusterbreed, en de leden van een node die uitvalt worden automatisch verwijderd zodat u nooit spookleden toont.

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

Weten wanneer het cluster gereed is

Elk cluster stelt zijn connectiviteit beschikbaar zodat u op de backplane kunt wachten voordat u begint te publiceren, of de gezondheid van nodes in een dashboard kunt tonen:

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

In .NET zijn dezelfde signalen OnPeerConnected / OnPeerDisconnected, de eigenschap ConnectedPeerCount en IsReady.

Hoe het samenwerkt met de rest van de bibliotheek

Clustering bevindt zich onder uw protocolcode, dus er verandert verder niets. Dezelfde Publish, channel-abonnementen, QoS-bevestigingen en Presence-API's die u al gebruikt blijven werken, nu over elke node heen. De mesh-engine heeft geen externe service nodig, waardoor een implementatie met twee of drie nodes triviaal is; Redis is er voor wanneer u groter schaalt. Bij de bibliotheek wordt een demo met twee nodes geleverd (02.WebSocket_Protocols\14.MultiNode_Clustering in Delphi, samples\ClusterDemo in .NET) zodat u op uw eigen machine een bericht over nodes heen kunt zien gaan.

Beschikbaarheid

Multi-node clustering is een functie van de Enterprise-editie en compileert van Delphi 7 tot en met 13 (Win32/Win64, Linux64, macOS, Android en iOS) en in de managed .NET-editie.

Klanten met een actief abonnement kunnen de nieuwe build downloaden uit het klantengedeelte. Trial-gebruikers kunnen het bijgewerkte installatieprogramma ophalen op esegece.com/products/websockets/download.

Vragen, feedback of hulp nodig om dit in uw implementatie in te bouwen? Neem contact op — u krijgt antwoord van de mensen die de code hebben geschreven.