145 votes

Équilibrage de la charge des sockets web

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

J'ai un serveur qui prend en charge les web sockets. Les navigateurs se connectent à mon site et chacun d'entre eux ouvre un socket web pour 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, j'augmentais la capacité en ajoutant un deuxième serveur et un équilibreur de charge devant les deux serveurs web.

Avec les web sockets, la connexion doit se faire directement avec le serveur web, et non 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 connectent à l'équilibreur de charge, je ne pourrais pas prendre en charge plus de 64 000 utilisateurs simultanés.

Alors comment je fais

  1. faire en sorte que le client se connecte 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 l'équilibreur de charge (ou autre) modifie aléatoirement l'URL pour le script, chaque fois que la page est initialement demandée ?

  2. gérer un début d'ondulation ? 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 absent pendant un certain temps. Je suppose donc que je devrais retourner à l'équilibreur de charge pour demander l'adresse du prochain nœud à utiliser ?

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

134voto

oberstet Points 7409

Mettez un équilibreur de charge L3 qui distribue les paquets IP en fonction du hachage source-IP-port à votre ferme de serveurs WebSocket. Puisque l'équilibreur L3 ne maintient aucun état (en utilisant le hachage source-IP-port), il s'adaptera à la vitesse du fil sur du matériel bas de gamme (disons 10GbE). Comme la distribution est déterministe (en utilisant le hachage source-IP-port), elle fonctionnera avec TCP (et donc WebSocket).

Notez également qu'une limite dure de 64k ne s'applique qu'à sortant TCP/IP pour une adresse IP (source) donnée. Il ne s'applique pas au TCP/IP entrant. Nous avons testé Autobahn (un serveur WebSocket haute performance) avec 200 000 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 poignée de main WebSocket initiale. Dans ce cas, l'équilibreur de charge doit maintenir un état (quelle paire IP-port source va vers quel noeud backend). Il pourra probablement s'adapter à des millions de connexions avec une bonne configuration.

Avertissement : je suis l'auteur original d'Autobahn et je travaille pour Tavendo.

9voto

Convolver Points 191

Notez que si votre logique de serveur websocket fonctionne sur nodejs avec socket.io, vous pouvez indiquer à socket.io d'utiliser un magasin clé/valeur 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 parmi les instances du serveur.

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

Voir : Socket IO - Utilisation de plusieurs nœuds

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

2voto

David Points 11

Vous pouvez également réaliser un équilibrage de charge de couche 7 avec l'inspection et la "fonctionnalité de routage".

Voir "Comment inspecter et équilibrer la charge du trafic WebSockets à l'aide du gestionnaire de trafic Stingray et, le cas échéant, comment gérer le trafic WebSockets et HTTP reçu sur la même adresse IP et le même port". https://splash.riverbed.com/docs/DOC-1451

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X