with socket node metodos examples create con node.js redis rabbitmq scalability socket.io

node.js - node - socket io socket io js



Arquitectura de escalamiento SocketIO y requisitos de grandes salas (4)

Estamos usando socketIO en una gran aplicación de chat.

En algunos puntos queremos enviar "presencia" (disponibilidad del usuario) a todos los demás usuarios.

io.in(''room1'').emit(''availability:update'', {userid=''xxx'', isAvailable: false});

La sala 1 puede contener muchos usuarios (máximo 500). Observamos un aumento significativo en nuestra carga de NodeJS cuando se activan muchas actualizaciones de disponibilidad.

La idea era usar algo similar a redis store con Socket IO. Tener clientes de navegador web para conectarse a diferentes servidores NodeJS.

Cuando queremos emitir a una sala, enviamos la carga útil de "emitir a sala1" a todos los demás procesos de NodeJS utilizando Redis PubSub ZeroMQ o incluso RabbitMQ para la persistencia. Cada proceso llamará a su propio io.in(''room1'').emit para apuntar a su subconjunto de usuarios conectados.

Una de las preocupaciones con esta configuración es que la comunicación entre procesos puede estar bastante ocupada y me preguntaba si podría convertirse en un problema en el futuro.

Aquí está la arquitectura que tengo en mente.


¿Podrías hacer cambios por lotes y solo distribuirlos cada 5 segundos aproximadamente? En otras palabras, en cada servidor de nodo, simplemente tome una ''instantánea'' cada X segundos del estado actual de todos los usuarios (por ejemplo, ''conectado'', ''inactivo'', etc.) y luego envíelo a los otros servidores relevantes de su clúster .

Cada servidor hace lo mismo, cada 5 segundos aproximadamente, envía el mismo mensaje, de solo los cambios en el estado del usuario, como una matriz de objetos por lotes a todos los clientes conectados.

En este momento, estoy bastante sorprendido de que esté intentando enviar información sobre cada usuario como un paquete. El procesamiento por lotes parece que resolvería su problema bastante bien, ya que también haría un mejor uso de los tamaños de paquetes estándar que normalmente se transmiten a través de enrutadores y conmutadores.


En cuanto a la función de usuarios disponibles, creo que hay dos alternativas, puede crear una "Cola de usuarios" en la que se incluirán los "datos públicos" de los usuarios conectados o puede usar la información de enlace de intercambios para mostrar los usuarios conectados. Si usa una "cola de usuario", esta será la misma para cada "sala" y podrá actualizarla cuando un usuario salga, "haciendo estallar" su mensaje de estado de la cola (aunque tendrá que "reorganizar" todos los mensajes de la cola para ello).

Sin embargo, creo que RabbitMQ está diseñado para la comunicación asíncrona y no es una aproximación muy útil tener un registro de presencia o no de los usuarios. Creo que es mejor para aplicaciones en las que no se sabe cuándo el usuario recibirá el mensaje y su "disponibilidad real" ("arquitecturas de fuego y olvido"). ZeroMQ requiere más trabajo desde cero, pero podría implementar algo más específico para su situación con un mejor rendimiento.

Un ejemplo de publicación / suscripción del sitio RabbitMQ podría ser un buen punto para comenzar un nuevo diseño como el suyo, en el que se envía un mensaje a varios usuarios al mismo tiempo. En resumen, crearé dos colas para el usuario (recibir y enviar mensajes de cola) y usaré intercambios específicos para cada "chat de sala" que controla que los usuarios estén en cada sala utilizando la información del enlace de intercambio. Siempre tiene dos colas para el usuario y crea intercambios para vincularlo a una o más "salas de chat".

Espero que esta respuesta te sea útil, disculpa mi mal inglés.


Este es el enfoque común para compartir datos a través de varios procesos Socket.io. Lo has hecho bien, hasta ahora, con un solo proceso y un solo hilo. Podría suponer que podría elegir cualquiera de las tecnologías mencionadas para comunicar datos compartidos sin tener que resolver ningún problema de rendimiento.

Si todo lo que necesitas es IPC, quizás puedas echar un vistazo a Faye . Sin embargo, si necesita conservar algunos datos, puede iniciar un clúster de Redis con tantos maestros de Redis como CPU, aunque esto agregará un ruido de red menor para Pub / Sub.