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 (
clusterMesh) — geen externe infrastructuur. Elke node luistert op een clusterpoort en maakt rechtstreeks verbinding met zijn peers. Ideaal voor kleine clusters die "gewoon moeten werken" zonder dat er iets extra geïnstalleerd hoeft te worden. - Redis (
clusterRedis) — gebruikt een Redis-server die u al draait als de Pub/Sub-backplane, voor grotere implementaties.
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.
