J'ai une question sur la façon d'équilibrer la charge des sockets Web.
J'ai un serveur qui supporte les sockets web. Les navigateurs se connectent à mon site et chacun ouvre un socket Web sur www.mydomain.com
. De cette façon, mon application de réseau social peut envoyer des messages aux clients.
Traditionnellement, en utilisant uniquement les requêtes HTTP, je souhaitais passer à la vitesse supérieure 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 établie avec le serveur Web, et non avec les équilibreurs de charge, car si une machine a une limite physique de 64k ports ouverts et que les clients se connectaient à l'équilibreur de charge, je ne pouvais pas prendre en charge. plus de 64 000 utilisateurs simultanés.
Alors, comment puis-je -
obliger le client à se connecter directement au serveur Web (plutôt qu'à l'équilibreur de charge) lors du chargement de la page? Dois-je simplement charger le code 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 demandée?
gérer un début d'ondulation? Le navigateur remarquera que la connexion est fermée lorsque le serveur Web est arrêté. Je peux écrire du code JavaScript pour tenter de rouvrir la connexion, mais le nœud sera parti pendant un moment. Je suppose donc que je devrais revenir à l'équilibreur de charge pour interroger l'adresse du prochain nœud à utiliser?
Je me demandais si les équilibreurs de charge envoyaient une redirection sur la demande initiale, de sorte que le navigateur demande initialement www.mydomain.com
Et soit redirigé vers www34.mydomain.com
. Cela fonctionne assez bien jusqu'à ce que le nœud tombe en panne - et que des sites comme Facebook ne le fassent pas. Comment font-ils?
Placez un équilibreur de charge L3 qui distribue les paquets IP basés sur le hachage source-IP-port sur votre batterie de serveurs WebSocket. Dans la mesure où l'équilibreur L3 ne maintient aucun état (à l'aide du port source IP haché), il passera à la vitesse de transmission sur le matériel bas de gamme (par exemple, 10 GbE). Comme la distribution est déterministe (en utilisant un port source-IP haché), elle fonctionnera avec TCP (et donc WebSocket).
Notez également qu'une limite stricte de 64 Ko s'applique uniquement à sortant TCP/IP pour une adresse IP donnée (source). Cela ne s'applique pas à TCP/IP entrant. Nous avons testé Autobahn (un serveur WebSocket haute performance) avec 200 000 connexions actives sur un processeur à 2 cœurs, 4 Go RAM VM.
Notez également que vous pouvez effectuer l’équilibrage de charge de L7 sur le chemin HTTP annoncé lors de la prise de contact WebSocket initiale. Dans ce cas, l'équilibreur de charge doit conserver l'état (quelle paire source-IP va à quel nœud principal). Il s’agira probablement de millions de connexions malgré une configuration décente.
Disclaimer: Je suis l'auteur original de Autobahn et le travail pour Tavendo.
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 propagent 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 Redis peut devenir le goulot d'étranglement ...
Vous pouvez également réaliser un équilibrage de charge de couche 7 avec inspection et "fonctionnalité de routage"
Voir "Comment inspecter et équilibrer le trafic WebSockets à l'aide de Stingray Traffic Manager 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