Sockets Web d'équilibrage de charge


104

J'ai une question sur la façon d'équilibrer la charge des sockets Web.

J'ai un serveur qui prend en charge les sockets Web. Les navigateurs se connectent à mon site et chacun ouvre une prise Web www.mydomain.com. De cette façon, mon application de réseau social peut envoyer des messages aux clients.

Traditionnellement, en utilisant uniquement des requêtes HTTP, je passerais à l'échelle en ajoutant un deuxième serveur et un équilibreur de charge devant les deux serveurs Web.

Avec les sockets Web, la connexion doit être directement avec le serveur Web, pas avec les équilibreurs de charge, car si une machine a une limite physique de 64 000 ports ouverts, par exemple, et que les clients se connectaient à l'équilibreur de charge, je ne pourrais pas prendre en charge plus de 64 000 utilisateurs simultanés.

Alors, comment puis-je -

  1. amener le client à se connecter directement au serveur Web (plutôt qu'à l'équilibreur de charge) lorsque la page se charge? Dois-je simplement charger le JavaScript à partir d'un nœud et les équilibreurs de charge (ou autre) modifient de manière aléatoire l'URL du script, chaque fois que la page est initialement demandée?

  2. gérer un début de vague? Le navigateur remarquera que la connexion est fermée lorsque le serveur Web s'arrête. Je peux écrire du code JavaScript pour tenter de rouvrir la connexion, mais le nœud sera parti pendant un certain temps. Donc, je suppose que je devrais revenir à l'équilibreur de charge pour interroger l'adresse du prochain nœud à utiliser?

  3. Je me suis demandé si les équilibreurs de charge envoyaient une redirection sur la demande initiale, de sorte que le navigateur demande initialement www.mydomain.comet soit redirigé vers www34.mydomain.com. Cela fonctionne très bien, jusqu'à ce que le nœud tombe en panne - et des sites comme Facebook ne le font pas. Comment font-ils?


1
Vous pouvez équilibrer la charge au niveau de la couche réseau, comme suggéré ici
Chris Snow

1
Il existe également des approches alternatives telles que l'équilibrage de charge basé sur DNS ou l'utilisation d'un serveur d'orchestration basé sur http. J'ai essayé de résumer les avantages et les inconvénients de chaque approche sur deepstream.io/blog/load-balancing-websocket-connections
wolframhempel

@wolframhempel Link est mort. :-(
Emile Cormier

Réponses:


94

Placez un équilibreur de charge L3 qui distribue les paquets IP en fonction du hachage du port IP source à votre batterie de serveurs WebSocket. Étant donné que l'équilibreur L3 ne conserve aucun état (en utilisant le port IP source haché), il évoluera en fonction de la vitesse du câble sur du matériel bas de gamme (par exemple 10 GbE). Puisque la distribution est déterministe (en utilisant le port IP source haché), elle fonctionnera avec TCP (et donc WebSocket).

Notez également qu'une limite stricte de 64 Ko s'applique uniquement au TCP / IP sortant pour une adresse IP (source) donnée. Il ne s'applique pas au TCP / IP entrant. Nous avons testé Autobahn (un serveur WebSocket hautes performances) avec 200k connexions actives sur une VM à 2 cœurs et 4 Go de RAM.

Notez également que vous pouvez effectuer un équilibrage de charge L7 sur le chemin HTTP annoncé lors de la négociation WebSocket initiale. Dans ce cas, l'équilibreur de charge doit maintenir l'état (quelle paire IP-port source va à quel nœud de backend). Il atteindra probablement des millions de connexions néanmoins avec une configuration décente.

Avis de non-responsabilité: Je suis l'auteur original d'Autobahn et je travaille pour Tavendo.


Je chargerais donc ma bibliothèque javascript à partir de l'URL de l'équilibreur de charge et donnerais l'URL de l'équilibreur de charge lorsque je crée le socket Web en javascript - vous voulez dire qu'il est transparent pour le navigateur? C'est cool!
John Smith

1
Oui, il n'y a qu'une seule URL, et le nom d'hôte de cette dernière doit être résolu par votre équilibreur de charge. Le serveur principal WebSocket a des adresses IP internes (non publiques) et peut éventuellement fonctionner sur des ports différents du port public également. La seule mise en garde est que vous devrez peut-être indiquer aux serveurs WebSocket quel est leur nom d'hôte public visible, leur IP, leur port, car les serveurs WebSocket conformes vérifieront que l'URL fournie dans l'en-tête HTTP de la négociation WS correspond au nom d'hôte / ip / port qu'ils écoutent.
oberstet le

Je n'ai pas beaucoup de connexions websocket à équilibrer mais j'ai beaucoup de trafic dans une ou disons très peu de connexions. pour simplifier, disons une connexion maintenant, comment puis-je équilibrer les demandes passant par une connexion Web socket?
user1870400

Quand je fais plus de connexions 5000+ dans java websocket, cela ne libère pas de mémoire ... y a-t-il une solution?
Poonam Patel

3

Notez que si la logique de votre serveur websocket s'exécute sur nodejs avec socket.io, vous pouvez indiquer à socket.io d'utiliser un magasin de clés / valeurs Redis partagé pour la synchronisation. De cette façon, vous n'avez même pas à vous soucier de l'équilibreur de charge, les événements se propageront entre les instances de serveur.

var io = require('socket.io')(3000);
var redis = require('socket.io-redis'); 
io.adapter(redis({ host: 'localhost', port: 6379 }));

Voir: http://socket.io/docs/using-multiple-nodes/

Mais à un moment donné, je suppose que les redis peuvent devenir le goulot d'étranglement ...


2

Vous pouvez également réaliser un équilibrage de charge de couche 7 avec inspection et «fonctionnalité de routage»

Consultez "Comment inspecter et équilibrer la charge du trafic WebSockets à l'aide de Stingray Traffic Manager et, si nécessaire, comment gérer le trafic WebSockets et HTTP qui est reçu sur la même adresse IP et le même port." https://splash.riverbed.com/docs/DOC-1451


2
J'ai dû faire des recherches pour trouver les informations que vous avez liées. La machine de retour m'a aidé à localiser une copie en direct de cet article: community.pulsesecure.net/t5/Pulse-Secure-vADC/…
Wyck
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.