Klastrowanie sgcWebSockets — skalowanie serwerów WebSocket na wielu węzłach | Blog eSeGeCe

Klastrowanie sgcWebSockets — skalowanie serwerów WebSocket na wielu węzłach

· Komponenty

Serwer WebSocket działający w pojedynczym procesie to nic trudnego. W chwili, gdy umieścisz dwie lub więcej instancji serwera za load balancerem, coś po cichu się psuje: każdy klient łączy się z dokładnie jednym węzłem, więc wiadomość opublikowana na węźle A nigdy nie dociera do subskrybentów znajdujących się na węźle B. Kanały, rozgłaszanie i Presence zaczynają działać połowicznie. To najczęstszy powód, dla którego zespoły wyrastają z biblioteki WebSocket i migrują gdzie indziej.

Nowy komponent TsgcWSCluster zamyka tę lukę. Umieść go obok swojego serwera, skieruj węzły na siebie nawzajem, a zdarzenie publikacji lub Presence na dowolnym węźle dotrze do subskrybentów połączonych z każdym węzłem, przy czym Twój istniejący kod Publish / kanałów / Presence pozostaje bez zmian. Ten wpis omawia dwa silniki backplane, konfigurację oraz gotowe do wklejenia przykłady dla Delphi i .NET.

Dwa silniki backplane

Klastrowanie działa poprzez backplane, z którym łączy się każdy węzeł. Gdy klient publikuje na węźle, ten węzeł dostarcza wiadomość swoim lokalnym subskrybentom i przekazuje ją do backplane; każdy inny węzeł ją otrzymuje i rozsyła do swoich lokalnych subskrybentów. Pętle są eliminowane poprzez oznaczanie każdej wiadomości identyfikatorem węzła pochodzenia.

Backplane wybierasz za pomocą właściwości EngineType:

Backplane typu mesh (zero infrastruktury)

Silnik mesh to najszybszy sposób na utworzenie klastra. Nadaj każdemu węzłowi ClusterPort do nasłuchiwania oraz host:port jego peerów, a następnie wykonaj Attach protokołu sgc, aby jego pub/sub kanałów (oraz Presence) został objęty klastrowaniem:

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;

To cała zmiana. Klient połączony z tym węzłem może wykonać Publish na kanał, a klienci na pozostałych dwóch węzłach otrzymają wiadomość, dokładnie tak, jakby wszyscy byli na jednym serwerze. Sesje sticky nie są wymagane.

Backplane Redis

Dla większych wdrożeń przełącz silnik na clusterRedis i skieruj go na swój serwer Redis. Wszystko powyżej backplane — kanały, Presence, Twój kod aplikacji — pozostaje takie samo:

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

Zarządzana edycja sgcWebSockets udostępnia ten sam komponent. Dołącz klaster do protokołu sgc serwera i uruchom go — publikacja na jednym węźle dociera do subskrybentów na pozostałych:

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;

W tej wersji edycja .NET dostarcza silnik mesh; backplane Redis jest dostępny w edycji Delphi / C++Builder.

Presence w skali całego klastra

Presence — „kto jest online w tym kanale” — to funkcja, która najbardziej cierpi, gdy serwer się skaluje, ponieważ każdy węzeł widzi tylko swoich własnych członków. TsgcWSCluster to naprawia: wykonaj Attach protokołu Presence w taki sam sposób, w jaki dołączasz protokół sgc, a lista członków staje się sumą ze wszystkich węzłów. Zdarzenia dołączenia / opuszczenia propagują się w skali całego klastra, a węzeł, który ulega awarii, ma swoich członków automatycznie usuwanych, więc nigdy nie pokazujesz członków-duchów.

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

Wiedza o tym, kiedy klaster jest gotowy

Każdy klaster udostępnia informacje o swojej łączności, dzięki czemu możesz poczekać na backplane, zanim zaczniesz publikować, lub pokazać kondycję węzłów na pulpicie:

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

W .NET te same sygnały to OnPeerConnected / OnPeerDisconnected, właściwość ConnectedPeerCount oraz IsReady.

Jak to współgra z resztą biblioteki

Klastrowanie znajduje się poniżej kodu Twojego protokołu, więc nic innego się nie zmienia. Te same API Publish, subskrypcje kanałów, potwierdzenia QoS i Presence, których już używasz, działają dalej, teraz na wszystkich węzłach. Silnik mesh nie potrzebuje żadnej zewnętrznej usługi, co sprawia, że wdrożenie dwu- lub trzywęzłowe jest trywialne; Redis jest dostępny, gdy skalujesz większe. Z biblioteką dostarczane jest demo dwuwęzłowe (02.WebSocket_Protocols\14.MultiNode_Clustering w Delphi, samples\ClusterDemo w .NET), dzięki czemu możesz zobaczyć, jak wiadomość przechodzi między węzłami na Twojej własnej maszynie.

Dostępność

Klastrowanie wielowęzłowe to funkcja edycji Enterprise i kompiluje się od Delphi 7 do 13 (Win32/Win64, Linux64, macOS, Android oraz iOS) oraz w zarządzanej edycji .NET.

Klienci z aktywną subskrypcją mogą pobrać nową kompilację ze strefy klienta. Użytkownicy wersji próbnej mogą pobrać zaktualizowany instalator pod adresem esegece.com/products/websockets/download.

Pytania, opinie lub pomoc w podłączeniu tego do Twojego wdrożenia? Skontaktuj się z nami — otrzymasz odpowiedź od ludzi, którzy napisali ten kod.