Реализация Pub/ Sub в nodeJS
Я играл с различными реализациями публикации / подписки для nodeJS, и мне было интересно, какая из них лучше всего подойдет для конкретного приложения. Требования приложения включают в себя синхронизацию объектов в режиме реального времени в многоканальной многопользовательской трехмерной среде.
Я начал с использования socket.io, создал базовый массив каналов, и когда пользователи отправляют сообщения, он перебирает пользователей в этом канале и отправляет сообщение клиенту пользователя. Это работало хорошо, и у меня не было проблем с этим.
Для сохранения объектов я добавил поддержку Redis с помощью node_redis. Затем я заменил цикл client.send в массиве каналов на Redis pub/sub как слой абстракции. Но я заметил, что мне нужно было создать новый клиент Redis для каждого пользователя, который сделал подписку. И мне все еще нужно было хранить информацию о клиенте socket.io для отправки сообщений на публикацию. Насколько это масштабируемо? Есть ли другие (лучшие) реализации или дальнейшие оптимизации, которые я мог бы сделать? Чтобы ты делал?
5 ответов
Для сохранения объектов я добавил поддержку Redis с помощью node_redis. Затем я заменил цикл client.send в массиве каналов на Redis pub/sub как слой абстракции. Но я заметил, что мне нужно было создать новый клиент Redis для каждого пользователя, который сделал подписку. И мне все еще нужно было хранить информацию о клиенте socket.io для отправки сообщений на публикацию. Насколько это масштабируемо? Есть ли другие (лучшие) реализации или дальнейшие оптимизации, которые я мог бы сделать? Чтобы ты делал?
Да, вы должны создать новый клиент Redis для каждого запроса ввода-вывода. Это тяжелый и не масштабируемый. Но создание нового клиентского подключения Redis не занимает много памяти. Так что, если количество пользователей вашей системы не превышает 5000, это нормально. Для масштабирования вы можете добавить в подчиненный сервер Redis, чтобы разрешить интенсивную публикацию и подписку, и если вы беспокоитесь о создании большого количества подключений, вы можете увеличить вашу ОС uLIMIT.
Вам не нужно хранить клиент socket.io в отправленном сообщении. После того как redis получил подписанное сообщение канала. Это отправит сообщение определенному клиенту io.
subscribe.on("message",function(channel,message) {
var msg = { message: [client.sessionId, message] };
buffer.push(msg);
if (buffer.length 15) buffer.shift();
client.send(msg); > });
Чтобы подписаться на многоканальный. Я предлагаю вам предварительно сохранить всех пользователей с более чем одним каналом (вы можете использовать хранилище Mongodb или Redis).
var store = redis.createClient();
var subscriber= redis.createClient()
store.hgetall(UID, function(e, obj){
subscriber.subscribe(obj.ChannelArray.toArray());
})
Я использую Faye.js. Серьезно простейшая реализация pub/sub, которую я смог найти. Может быть, это поможет!
Попробуйте посмотреть на этот вопрос относительно redis pub/sub и socket.io.
Или вы можете попробовать Джаггернаут. Это с помощью socket.io + redis pub sub middleware + node.js. Поддержите все транспорты. Это поможет вам обработать все каналы подписки или публикации между клиентом и Redis. Juggernaut является масштабируемым, но он затрагивает только накладные расходы на Redis, и он не поддерживает аутентификацию (вы можете с этим справиться). Однако redis может записывать / читать>150 кбит / с, поэтому для вашего случая это не должно быть проблемой.
FYI Socket.io v0.7 будет поддерживать каналы и должен упростить ваш существующий код (больше нет зависимостей pub/sub lib)
Смотрите: http://cl.ly/0B0C3f133K1m3j422n0K