Clustering sgcWebSockets — Faites évoluer vos serveurs WebSocket sur plusieurs nœuds | Blog eSeGeCe

Clustering sgcWebSockets — Faites évoluer vos serveurs WebSocket sur plusieurs nœuds

· Composants

Un serveur WebSocket qui tourne sur un seul processus, c'est facile. Dès que vous placez deux instances de serveur ou plus derrière un répartiteur de charge, quelque chose casse en silence : chaque client se connecte à exactement un nœud, donc un message publié sur le nœud A n'atteint jamais les abonnés situés sur le nœud B. Les canaux, les diffusions et le Presence deviennent tous à moitié aveugles. C'est la raison la plus courante pour laquelle les équipes finissent par dépasser les limites d'une bibliothèque WebSocket et migrent ailleurs.

Le nouveau composant TsgcWSCluster comble cette lacune. Placez-le à côté de votre serveur, pointez les nœuds les uns vers les autres, et une publication ou un événement Presence sur n'importe quel nœud atteint les abonnés connectés à chaque nœud, sans rien changer à votre code Publish / canal / Presence existant. Cet article parcourt les deux moteurs de backplane, la configuration et des exemples Delphi et .NET prêts à coller.

Deux moteurs de backplane

Le clustering fonctionne grâce à un backplane auquel chaque nœud se connecte. Lorsqu'un client publie sur un nœud, ce nœud délivre le message à ses propres abonnés locaux et le transmet au backplane ; tous les autres nœuds le reçoivent et le redistribuent à leurs abonnés locaux. Les boucles sont évitées en marquant chaque message avec l'identifiant du nœud d'origine.

Vous choisissez le backplane avec la propriété EngineType :

Backplane maillé (sans infrastructure)

Le moteur maillé est le moyen le plus rapide de mettre en cluster. Donnez à chaque nœud un ClusterPort sur lequel écouter et le host:port de ses pairs, puis utilisez Attach sur le protocole sgc pour que sa pub/sub de canal (et le Presence) soit en 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;

C'est tout le changement. Un client connecté à ce nœud peut faire un Publish sur un canal et les clients sur les deux autres nœuds le reçoivent, exactement comme s'ils étaient tous sur un seul serveur. Aucune session persistante requise.

Backplane Redis

Pour les déploiements de plus grande envergure, basculez le moteur sur clusterRedis et pointez-le vers votre serveur Redis. Tout ce qui se trouve au-dessus du backplane — canaux, Presence, votre code applicatif — reste inchangé :

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'édition managée de sgcWebSockets expose le même composant. Attachez le cluster au protocole sgc du serveur et démarrez-le — une publication sur un nœud atteint les abonnés des autres :

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;

Dans cette version, l'édition .NET embarque le moteur mesh ; le backplane Redis est disponible sur l'édition Delphi / C++Builder.

Presence à l'échelle du cluster

Le Presence — « qui est en ligne dans ce canal » — est la fonctionnalité qui souffre le plus lorsqu'un serveur monte en charge, car chaque nœud ne voit que ses propres membres. TsgcWSCluster corrige cela : utilisez Attach sur le protocole Presence de la même manière que vous attachez le protocole sgc, et la liste des membres devient l'union sur l'ensemble des nœuds. Les événements de connexion / déconnexion se propagent à l'échelle du cluster, et les membres d'un nœud qui tombe sont automatiquement purgés afin que vous n'affichiez jamais de membres fantômes.

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

Savoir quand le cluster est prêt

Chaque cluster expose sa connectivité afin que vous puissiez attendre le backplane avant de commencer à publier, ou faire remonter l'état de santé des nœuds dans un tableau de bord :

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

Sur .NET, les mêmes signaux sont OnPeerConnected / OnPeerDisconnected, la propriété ConnectedPeerCount et IsReady.

Comment cela se combine avec le reste de la bibliothèque

Le clustering se situe en dessous de votre code de protocole, donc rien d'autre ne change. Les mêmes API Publish, abonnements aux canaux, accusés de réception QoS et Presence que vous utilisez déjà continuent de fonctionner, désormais sur l'ensemble des nœuds. Le moteur maillé ne nécessite aucun service externe, ce qui rend un déploiement à deux ou trois nœuds trivial ; Redis est là pour le moment où vous monterez davantage en charge. Une démo à deux nœuds est livrée avec la bibliothèque (02.WebSocket_Protocols\14.MultiNode_Clustering sur Delphi, samples\ClusterDemo sur .NET) afin que vous puissiez voir un message traverser les nœuds sur votre propre machine.

Disponibilité

Le clustering multi-nœuds est une fonctionnalité de l'édition Enterprise et se compile de Delphi 7 à 13 (Win32/Win64, Linux64, macOS, Android et iOS) ainsi que sur l'édition managée .NET.

Les clients disposant d'un abonnement actif peuvent télécharger la nouvelle version depuis l'espace client. Les utilisateurs en version d'essai peuvent récupérer l'installateur mis à jour sur esegece.com/products/websockets/download.

Des questions, des retours ou besoin d'aide pour intégrer ceci dans votre déploiement ? Contactez-nous — vous recevrez une réponse de la part des personnes qui ont écrit le code.