Подтвердить что ты не робот

Архитектура масштабирования SocketIO и требования к большим комнатам

Мы используем socketIO в большом приложении чата.

В некоторых случаях мы хотим отправить "присутствие" (доступность пользователя) всем другим пользователям.

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

В комнате 1 может быть много пользователей (максимум 500). Мы наблюдаем значительный подъем в нашей нагрузке NodeJS, когда запускается много обновлений доступности.

Идея заключалась в том, чтобы использовать что-то похожее на redis store с Socket IO. Попросите клиентов веб-браузера подключиться к различным серверам NodeJS.

Когда мы хотим выпустить в комнату, мы отправляем полезную нагрузку "emit to room1" на все остальные процессы NodeJS, используя Redis PubSub ZeroMQ или даже RabbitMQ для сохранения. Каждый процесс сам назовет его собственный io.in('room1').emit, чтобы нацелить его подмножество подключенных пользователей.

Одна из проблем, связанных с этой настройкой, заключается в том, что межпроцессная связь может стать довольно занятой, и мне было интересно, может ли она стать проблемой в будущем.

Вот архитектура, которую я имею в виду.

enter image description here

4b9b3361

Ответ 2

О доступных функциях пользователей, я думаю, что есть две альтернативы, вы можете создать "очередь пользователей", где будет содержимое "общедоступных данных" от подключенных пользователей, или вы можете использовать привязывающую информацию об обмене для подключенных пользователей шоу. Если вы используете "пользовательскую очередь", это будет одинаково для каждой "комнаты", и вы можете обновить его, когда пользователь выйдет, "выскочив" из своего сообщения о состоянии из очереди (хотя вам придется "реорганизовать" все сообщение очереди для него).

Тем не менее, я считаю, что RabbitMQ предназначен для асинхронной связи, и это не очень полезная аппроксимация, есть регистр для присутствия или нет у пользователей. Я думаю, что это лучше для приложений, где вы не знаете, когда пользователь получит сообщение и его "реальную доступность" ( "огонь и забыть архитектуры" ). ZeroMQ требует больше работы с нуля, но вы можете реализовать что-то более конкретное для вашей ситуации с лучшей производительностью.

Пример публикации/подписки с сайта RabbitMQ может быть хорошим моментом, чтобы начать новый дизайн, такой как ваш, где сообщение было отправлено нескольким пользователям одновременно. В заключение я создам две очереди для пользователя (получаю и отправляю сообщения о очереди), и я буду использовать определенные обмены для каждого "чата в комнате", контролирующего, что пользователи находятся в каждой комнате, используя информацию привязки обмена. Всегда у вас есть две очереди для пользователя, и вы создаете биржи для привязки к одному или нескольким "чатам".

Я надеюсь, что этот ответ может быть полезен для вас, извините за мой плохой английский.

Ответ 3

Не могли бы вы внести изменения и распространять их каждые 5 секунд или около того? Другими словами, на каждом сервере node просто сделайте "моментальный снимок" каждые X секунд текущего состояния всех пользователей (например, "подключен", "простоя" и т.д.), А затем отправьте их другим соответствующим серверам в ваш кластер.

Каждый сервер выполняет то же самое, каждые 5 секунд или около того он отправляет одно и то же сообщение - только изменения состояния пользователя - как один массив пакетных объектов для всех подключенных клиентов.

В настоящий момент я довольно удивлен, что вы пытаетесь отправить информацию о каждом пользователе в виде пакета. Пакетная обработка кажется, что она решит вашу проблему достаточно хорошо, так как она также будет лучше использовать стандартные размеры пакетов, которые обычно передаются через маршрутизаторы и коммутаторы.

Ответ 4

Это общий подход для обмена данными по нескольким процессам Socket.io. Пока что вы сделали хорошо, с одним процессом и одним потоком. Я мог бы предположить, что вы можете выбрать любую из упомянутых технологий для обмена общими данными без каких-либо проблем с производительностью.

Если вам нужно IPC, возможно, вы можете взглянуть на Faye. Однако, если вам нужно сохранить некоторые данные, вы можете запустить кластер Redis с таким количеством мастеров Redis, как у вас есть процессоры, хотя это добавит незначительный сетевой шум для Pub/Sub.