Prese web di bilanciamento del carico


104

Ho una domanda su come bilanciare il carico dei socket web.

Ho un server che supporta i web socket. I browser si connettono al mio sito e ognuno apre un web socket www.mydomain.com. In questo modo, la mia app di social network può inviare messaggi ai clienti.

Tradizionalmente, utilizzando solo richieste HTTP, scalerei aggiungendo un secondo server e un bilanciatore del carico davanti ai due server web.

Con i socket web, la connessione deve essere direttamente con il server web, non con i bilanciatori del carico, perché se una macchina ha un limite fisico di diciamo 64k porte aperte e i client si connettono al bilanciamento del carico, allora non potrei supportare più di 64k utenti simultanei.

Quindi come faccio a -

  1. convincere il client a connettersi direttamente al server web (piuttosto che al bilanciamento del carico) quando la pagina viene caricata? Carico semplicemente JavaScript da un nodo e il load balancer (o qualsiasi altra cosa) modifica in modo casuale l'URL per lo script, ogni volta che la pagina viene inizialmente richiesta?

  2. gestire un inizio ondulato? Il browser noterà che la connessione viene chiusa allo spegnimento del server web. Posso scrivere codice JavaScript per tentare di riaprire la connessione, ma il nodo sarà andato per un po '. Quindi immagino che dovrei tornare al bilanciamento del carico per interrogare l'indirizzo del nodo successivo da utilizzare?

  3. Mi chiedevo se i bilanciatori del carico inviassero un reindirizzamento alla richiesta iniziale, in modo che il browser inizialmente richieda www.mydomain.come venga reindirizzato a www34.mydomain.com. Funziona abbastanza bene, fino a quando il nodo non si interrompe e siti come Facebook non lo fanno. Come lo fanno?


1
È possibile bilanciare il carico a livello di rete, come suggerito qui
Chris Snow,

1
Esistono anche approcci alternativi come il bilanciamento del carico basato su DNS o l'utilizzo di un server di orchestrazione basato su http. Ho provato a riassumere i lati
positivi

@wolframhempel Link è morto. :-(
Emile Cormier

Risposte:


94

Metti un bilanciatore del carico L3 che distribuisca pacchetti IP in base all'hash della porta IP di origine alla server farm WebSocket. Poiché il bilanciatore L3 non mantiene alcuno stato (utilizzando la porta IP di origine con hash), scalerà alla velocità del cavo su hardware di fascia bassa (ad esempio 10GbE). Poiché la distribuzione è deterministica (utilizzando la porta IP-sorgente con hash), funzionerà con TCP (e quindi WebSocket).

Si noti inoltre che un limite rigido di 64k si applica solo al TCP / IP in uscita per un determinato indirizzo IP (di origine). Non si applica al TCP / IP in entrata. Abbiamo testato Autobahn (un server WebSocket ad alte prestazioni) con 200k connessioni attive su una VM a 2 core e 4 GB di RAM.

Si noti inoltre che è possibile eseguire il bilanciamento del carico L7 sul percorso HTTP annunciato durante l'handshake WebSocket iniziale. In tal caso, il sistema di bilanciamento del carico deve mantenere lo stato (quale coppia di porte IP di origine andrà a quale nodo di backend). Probabilmente scalerà a milioni di connessioni nonostante una configurazione decente.

Disclaimer: sono l'autore originale di Autobahn e lavoro per Tavendo.


Quindi carico la mia libreria javascript dall'URL del bilanciamento del carico e fornisco l'URL del bilanciamento del carico quando creo il socket web in javascript - vuoi dire che è trasparente per il browser? È fantastico!
John Smith,

1
Sì, c'è solo 1 URL e il nome host di quest'ultimo dovrebbe risolversi nel tuo bilanciatore del carico. Il server di backend WebSocket ha IP interni (non pubblici) e opzionalmente può essere eseguito anche su porte diverse da quella pubblica. L'unico avvertimento è che potresti dover dire ai server WebSocket qual è il loro nome host, IP, porta pubblico visibile, poiché i server WebSocket conformi controlleranno che l'URL fornito nell'intestazione HTTP dell'handshake WS si adatti al nome host / ip / porta che hanno stanno ascoltando.
oberstet

Non ho molte connessioni websocket da bilanciare ma ho molto traffico in una o diciamo pochissime connessioni. per semplicità dire una connessione ora come posso bilanciare le richieste che passano attraverso una connessione web socket?
user1870400

Quando effettuo più connessioni 5000+ in java websocket non rilascia memoria .... c'è qualche soluzione?
Poonam Patel

3

Tieni presente che se la logica del server websocket viene eseguita su nodejs con socket.io, puoi dire a socket.io di utilizzare un archivio chiave / valore redis condiviso per la sincronizzazione. In questo modo non devi nemmeno preoccuparti del bilanciamento del carico, gli eventi si propagheranno tra le istanze del server.

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

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

Ma a un certo punto immagino che il redis possa diventare il collo di bottiglia ...


2

È inoltre possibile ottenere il bilanciamento del carico di livello 7 con ispezione e "funzionalità di instradamento"

Vedere "Come controllare e bilanciare il carico del traffico WebSocket utilizzando Stingray Traffic Manager e, quando necessario, come gestire WebSocket e il traffico HTTP ricevuto sullo stesso indirizzo IP e sulla stessa porta." https://splash.riverbed.com/docs/DOC-1451


2
Ho dovuto indagare per trovare le informazioni che hai collegato. La macchina del ritorno mi ha aiutato a trovare una copia live di quell'articolo: community.pulsesecure.net/t5/Pulse-Secure-vADC/…
Wyck
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.