Я получаю повторяющиеся сообщения в моем кластеризованном приложении node.js / socket.io / redis pub / sub

Я использую Node.js, Socket.io с Redisstore, Cluster от разработчиков Socket.io и Redis.

У меня есть приложение pub / sub, которое хорошо работает только на одном узле Node.js. Но при большой нагрузке максимально использует только одно ядро ​​сервера, поскольку Node.js не написан для многоядерных машин.

Как вы можете видеть ниже, сейчас я использую модуль Cluster от Learnboost, тех же людей, которые создают Socket.io.

Но когда я запускаю 4 рабочих процесса, каждый клиент браузера, который входит и подписывается, получает 4 копии каждого сообщения, опубликованного в Redis. Если есть три рабочих процесса, будет три копии.

Полагаю, мне нужно как-то перенести функциональность redis pub / sub в файл cluster.js.

Cluster.js

var cluster = require('./node_modules/cluster');

cluster('./app')
  .set('workers', 4)
  .use(cluster.logger('logs'))
  .use(cluster.stats())
  .use(cluster.pidfiles('pids'))
  .use(cluster.cli())
  .use(cluster.repl(8888))
  .listen(8000);

App.js

redis = require('redis'),
sys = require('sys');

var rc = redis.createClient();

var path = require('path')
  , connect = require('connect')
  , app = connect.createServer(connect.static(path.join(__dirname, '../')));

// require the new redis store
var sio = require('socket.io')
  , RedisStore = sio.RedisStore
  , io = sio.listen(app);

io.set('store', new RedisStore);io.sockets.on('connection', function(socket) {
    sys.log('ShowControl -- Socket connected: ' + socket.id);

    socket.on('channel', function(ch) {
        socket.join(ch)
        sys.log('ShowControl -- ' + socket.id + ' joined channel: ' + ch);
    });

    socket.on('disconnect', function() {
        console.log('ShowControll -- Socket disconnected: ' + socket.id);
    });
});

rc.psubscribe('showcontrol_*');

rc.on('pmessage', function(pat, ch, msg) {
    io.sockets.in(ch).emit('show_event', msg);
    sys.log('ShowControl -- Publish sent to channel: ' + ch);
});

// cluster compatiblity
if (!module.parent) {
  app.listen(process.argv[2] || 8081);
  console.log('Listening on ', app.address());
} else {
  module.exports = app;
}

client.html

<script src="http://localhost:8000/socket.io/socket.io.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.0/jquery.min.js"></script>
<script>
    var socket = io.connect('localhost:8000');
    socket.emit('channel', 'showcontrol_106');
    socket.on('show_event', function (msg) {
        console.log(msg);
        $("body").append('<br/>' + msg);
    });
</script>
6
задан Nick Messick 2 December 2011 в 22:00
поделиться