2012-07-25 30 views
7

Mi situación es que actualmente escribimos una aplicación en línea que usa Node.js en el lado del servidor con el oyente WebSocket. Tenemos dos partes diferentes: una sirve páginas y usa node.js y express + ejs, otra es una aplicación completamente diferente que solo incluye la biblioteca socket.io para websockets. Así que aquí llegamos a esta cuestión de la escalabilidad de la parte websockets.¿Equilibrio de carga basado en cookies para WebSockets?

Una de las soluciones que hemos encontrado es utilizar redis y compartir información de sockets entre servidores, pero debido a la arquitectura requerirá compartir mucha otra información, lo que generará una sobrecarga enorme en los servidores.

Después de esta introducción, mi pregunta es: ¿es posible usar el equilibrio de carga basado en cookies para websockets? Entonces, digamos que cada conexión desde el usuario con el servidor de cookie = servidor1 siempre será reenviada al servidor1 y cada conexión con el servidor de cookies = servidor2 será fw a servidor2 y la conexión sin tal cookie será de menor a menor servidor.

ACTUALIZACIÓN: como dice una 'respuesta', sí, sé que esto existe. Simplemente no recuerdo que ese nombre es una sesión pegajosa. Pero la pregunta es: ¿funcionará eso para websockets? ¿Hay alguna posible complicación?

+0

Esta es una pregunta que también estoy muy interesada, solo que no veo el problema con el balanceo de carga de las conexiones entrantes de los navegadores (solo llegará a uno de los servidores y se quedará con él), Estoy más interesado en cómo presionas a esos servidores desde tu back-end. Por ejemplo, tengo el servidor back-end que hace el trabajo real y luego envía mensajes al servidor websockets a través de un socket: ¿cómo sé a cuál presionar si tengo un clúster? Mi idea actual es mantener la lista de todas las conexiones abiertas en algún lugar de la base de datos central, sin estar seguro de si es la mejor manera de hacerlo. – KOHb

+0

@KOHb No tengo ningún back-end adicional detrás de los servidores de socket. Entonces es mucho más simple en mi caso. Pero por lo que dices, probaré el servidor Redis para este propósito. – AlexKey

Respuesta

5

Tuvimos un problema similar en nuestra pila de producción Node.js. Tenemos dos servidores que usan WebSockets que funcionan para casos de uso normal, pero ocasionalmente el balanceador de carga rebotará esta conexión entre los dos servidores, lo que causaría problemas. (Tenemos el código de sesión en el back-end que debería haberlo arreglado, pero no lo manejamos correctamente.)

Intentamos habilitar Sticky Session en el equilibrador de carga Barracuda frente a estos servidores pero encontramos que bloquearía WebSocket el tráfico debido a cómo operaba. No he investigado exactamente por qué, ya que hay poca información disponible en línea, pero parece que esto se debe a cómo el equilibrador quita los encabezados de una solicitud HTTP, toma la cookie y reenvía la solicitud al servidor back-end correcto. Como WebSockets comienza como HTTP pero luego se actualiza, el equilibrador de carga no notó la diferencia en la conexión e intentó hacer el mismo procesamiento HTTP. Esto causaría que la conexión WebSocket fallara, desconectando al usuario.

Lo siguiente es lo que tenemos actualmente en funcionamiento y que funciona muy bien. Todavía utilizamos los equilibradores de carga Barracuda en frente de nuestros servidores backend, pero no tenemos las sesiones adhesivas habilitadas en los balanceadores de carga. En nuestros servidores back-end, frente a nuestro servidor de aplicaciones, se encuentra HAProxy, que admite WebSockets correctamente, y puede proporcionar Sticky Sessions de forma indirecta.

lista de peticiones flujo de solicitudes de clientes entrantes

  1. golpea primaria Barracuda Load Balancer
  2. hacia delante del equilibrador de carga a cualquiera de los servidores back-end activos
  3. HAProxy recibe la solicitud y los controles para el nueva 'cookie adhesiva'
  4. Basado en la cookie, HAProxy lo reenvía al servidor de la aplicación de fondo correcta

Solicitud Diagrama de flujo

WebSocket Request /--> Barracuda 1 -->\ /--> Host 1 -->\ /--> App 1 
------------------->      -->    --> 
        \--> Barracuda 2 -->/ \--> Host 2 -->/ \--> App 1 

Cuando las flechas regresan a una petición, que significa la solicitud puede fluir a cualquiera de los puntos en el flujo.


configuración HAProxy detalles

backend app_1 
    cookie ha_app_1 insert 
    server host1 10.0.0.101:80011 weight 1 maxconn 1024 cookie host_1 check 
    server host2 10.0.0.102:80011 weight 1 maxconn 1024 cookie host_2 check 

En la configuración anterior:

  • cookie ha_app_1 insert es el nombre de la cookie actual utiliza
  • cookie host_1 check o cookie host_2 check establece el valor de la cookie
+0

Gracias por esta respuesta detallada. Pero, lamentablemente, todavía tenemos que usar mucho la sesión adhesiva para la conexión del socket. ¿Proxy la tubería o la redirige? – AlexKey

+0

Debido a los hallazgos en el protocolo WebSocket decidimos seguir con la siguiente solución: - cargar la conexión del sockets en el paso handhsake (está bien ya que handshake es solo HTTP) con sesión adhesiva y no proxy, pero redirigirlo - En caso de que cambios de estado: fuerza de reconexión del cliente, donde se cargará nuevamente al servidor adecuado en el handshake - servidores r expuestos dentro de la red del subdominio (smth como s1-socket.example.com, s2-socket.example.com, etc.) Pero todavía no tenemos implementaciones. Te actualizaré una vez que lo tengamos. – AlexKey

+0

Su primer comentario: Todavía tenemos que usar sesiones adhesivas, y la respuesta anterior es cómo implementamos Sticky Sessions a nuestra manera, lo que evitó el uso de Load Stickler Session. Su segundo comentario: Esto suena como un escenario que debería funcionar para usted. Todavía es bastante similar al nuestro aunque el equilibrador de carga de hardware no está en uso.Usamos HAProxy como nuestro único equilibrador de carga que proporciona la funcionalidad necesaria. –

Cuestiones relacionadas