Node.js,多线程和Socket.io

Dav*_*ard 10 javascript node.js socket.io

我希望让Socket.io 在Node.js v.0.6.0及更高版本中使用本机负载平衡("集群")进行多线程.

据我所知,Socket.io使用Redis来存储其内部数据.我的理解是:我们不想为每个工作者生成一个新的Redis实例,而是强制工作者使用与主服务器相同的Redis实例.因此,连接数据将在所有工作人员之间共享.

在主人中有类似的东西:

RedisInstance = new io.RedisStore;
Run Code Online (Sandbox Code Playgroud)

我们必须以某种方式传递RedisInstance给工人并做以下事情:

io.set('store', RedisInstance);
Run Code Online (Sandbox Code Playgroud)

受到使用旧的第三方集群模块的此实现的启发,我有以下非工作实现:

var cluster = require('cluster');
var http = require('http');
var numCPUs = require('os').cpus().length;

if (cluster.isMaster) {
  // Fork workers.
  for (var i = 0; i < numCPUs; i++) {
    cluster.fork();
  }

  var sio = require('socket.io')
  , RedisStore = sio.RedisStore
  , io = sio.listen(8080, options);

  // Somehow pass this information to the workers
  io.set('store', new RedisStore);

} else {
  // Do the work here
  io.sockets.on('connection', function (socket) {
    socket.on('chat', function (data) {
      socket.broadcast.emit('chat', data);
    })
  });
}
Run Code Online (Sandbox Code Playgroud)

思考?我可能会走向错误的方向,任何人都可以指出一些想法?

ale*_*lex 10

实际上你的代码应该是这样的:

var cluster = require('cluster');
var http = require('http');
var numCPUs = require('os').cpus().length;

if (cluster.isMaster) {
  // Fork workers.
  for (var i = 0; i < numCPUs; i++) {
    cluster.fork();
  }
} else {
  var sio = require('socket.io')
  , RedisStore = sio.RedisStore
  , io = sio.listen(8080, options);

  // Somehow pass this information to the workers
  io.set('store', new RedisStore);

  // Do the work here
  io.sockets.on('connection', function (socket) {
    socket.on('chat', function (data) {
      socket.broadcast.emit('chat', data);
    })
  });
}
Run Code Online (Sandbox Code Playgroud)

另一个选择是打开Socket.IO来监听多个端口并具有类似HAProxy负载平衡的东西.无论如何,你知道最重要的事情:使用RedisStore在进程外扩展!

资源:

http://nodejs.org/docs/latest/api/cluster.html
如何扩展socket.io?
如何在socket.io中重用redis连接?
节点:缩放socket.io/nowjs - 跨不同实例进行扩展
http://delicious.com/alessioaw/socket.io

  • HAProxy的优点:您可以在不同的端口上进行处理,您可以更仔细地监视它们并在它们死亡时重新启动(使用monit,upstart).同样是的,你需要为每个工人创建一个新的RedisStore.认为集群是child_process.fork()之上的一个实现,所以你基本上复制了应用程序N次(据我所知,进程共享相同的文件描述符). (2认同)