Zócalos web de equilibrio de carga

104

Tengo una pregunta sobre cómo equilibrar la carga de los sockets web.

Tengo un servidor que admite sockets web. Los navegadores se conectan a mi sitio y cada uno abre una conexión web a www.mydomain.com. De esa manera, mi aplicación de red social puede enviar mensajes a los clientes.

Tradicionalmente, usando solo solicitudes HTTP, escalaría agregando un segundo servidor y un equilibrador de carga frente a los dos servidores web.

Con los sockets web, la conexión tiene que ser directamente con el servidor web, no con los balanceadores de carga, porque si una máquina tiene un límite físico de, digamos, 64k puertos abiertos, y los clientes se conectan al balanceador de carga, entonces no puedo soportar más de 64.000 usuarios simultáneos.

Entonces, ¿cómo yo ...

  1. conseguir que el cliente se conecte directamente al servidor web (en lugar del equilibrador de carga) cuando se carga la página? ¿Simplemente cargo JavaScript desde un nodo y los balanceadores de carga (o lo que sea) modifican aleatoriamente la URL del script cada vez que se solicita la página inicialmente?

  2. manejar un comienzo de onda? El navegador notará que la conexión se cierra cuando el servidor web se apaga. Puedo escribir código JavaScript para intentar reabrir la conexión, pero el nodo desaparecerá por un tiempo. Entonces, supongo que tendría que volver al equilibrador de carga para consultar la dirección del siguiente nodo a usar.

  3. Me pregunté si los balanceadores de carga envían una redirección en la solicitud inicial, de modo que el navegador inicialmente solicita www.mydomain.comy se redirige a www34.mydomain.com. Eso funciona bastante bien, hasta que el nodo se cae, y sitios como Facebook no hacen eso. ¿Cómo lo hicieron?

John Smith
fuente
1
Puede equilibrar la carga en la capa de red, como se sugiere aquí
Chris Snow,
1
También existen enfoques alternativos como el equilibrio de carga basado en DNS o el uso de un servidor de orquestación basado en http. Intenté resumir las ventajas y desventajas de cada enfoque en deepstream.io/blog/load-balancing-websocket-connections
wolframhempel
@wolframhempel Link está muerto. :-(
Emile Cormier

Respuestas:

94

Coloque un equilibrador de carga L3 que distribuya paquetes IP basados ​​en el hash del puerto IP de origen a su granja de servidores WebSocket. Dado que el equilibrador L3 no mantiene ningún estado (utilizando el puerto IP de origen con hash), escalará a la velocidad del cable en hardware de gama baja (por ejemplo, 10 GbE). Dado que la distribución es determinista (utilizando el puerto IP de origen con hash), funcionará con TCP (y, por lo tanto, WebSocket).

También tenga en cuenta que un límite estricto de 64k solo se aplica a TCP / IP saliente para una dirección IP determinada (de origen). No se aplica a TCP / IP entrante. Hemos probado Autobahn (un servidor WebSocket de alto rendimiento) con 200k conexiones activas en una máquina virtual de 2 núcleos y 4 GB de RAM.

También tenga en cuenta que puede realizar el equilibrio de carga L7 en la ruta HTTP anunciada durante el protocolo de enlace inicial de WebSocket. En ese caso, el equilibrador de carga tiene que mantener el estado (qué par de puerto IP de origen va a qué nodo de backend). Probablemente escalará a millones de conexiones, sin embargo, con una configuración decente.

Descargo de responsabilidad: soy el autor original de Autobahn y trabajo para Tavendo.

oberstet
fuente
Entonces cargaría mi biblioteca javascript desde la URL del balanceador de carga y le daría la URL del balanceador de carga cuando creo el conector web en javascript, ¿quiere decir que es transparente para el navegador? ¡Esta genial!
John Smith
1
Sí, solo hay 1 URL y el nombre de host de esta última debería resolverse en su equilibrador de carga. El servidor backend de WebSocket tiene direcciones IP internas (no públicas) y, opcionalmente, puede ejecutarse en puertos diferentes del público también. La única advertencia es que es posible que deba decirle a los servidores WebSocket cuál es su nombre de host, IP y puerto visible público, ya que los servidores WebSocket que cumplan comprobarán que la URL proporcionada en el encabezado HTTP del protocolo de enlace WS se ajusta al nombre de host / ip / puerto que están escuchando.
oberstet
No tengo muchas conexiones websocket para equilibrar, pero tengo mucho tráfico en una o, digamos, muy pocas conexiones. para simplificar, digamos una conexión ahora, ¿cómo puedo equilibrar las solicitudes que pasan por una conexión de socket web?
user1870400
Cuando hago más conexiones 5000+ en java websocket, no libera memoria ... ¿hay alguna solución?
Poonam Patel
3

Tenga en cuenta que si la lógica de su servidor websocket se ejecuta en nodejs con socket.io, puede decirle a socket.io que use un almacén de claves / valores redis compartido para la sincronización. De esta manera, ni siquiera tiene que preocuparse por el equilibrador de carga, los eventos se propagarán entre las instancias del servidor.

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

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

Pero en algún momento supongo que redis puede convertirse en el cuello de botella ...

Convolver
fuente
2

También puede lograr el equilibrio de carga de capa 7 con inspección y "funcionalidad de enrutamiento"

Consulte "Cómo inspeccionar y equilibrar la carga del tráfico de WebSockets con Stingray Traffic Manager y, cuando sea necesario, cómo administrar el tráfico de WebSockets y HTTP que se recibe en la misma dirección IP y puerto". https://splash.riverbed.com/docs/DOC-1451

David
fuente
2
Tuve que investigar un poco para encontrar la información que vinculó. La máquina de retorno me ayudó a localizar una copia en vivo de ese artículo: community.pulsesecure.net/t5/Pulse-Secure-vADC/…
Wyck