一尘不染

Node.js,多线程和Socket.io

node.js

我希望让Socket.io 在Node.js
v.0.6.0及更高版本中与本机负载平衡(“集群”)一起工作。

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

像这样的主人:

RedisInstance = new io.RedisStore;

我们必须以某种方式传递RedisInstance给工人并执行以下操作:

io.set('store', RedisInstance);

受使用旧的第三方集群模块的此实现的启发,我有以下不可行的实现:

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);
    })
  });
}

有什么想法吗?我可能完全朝错误的方向前进,有人可以指出一些想法吗?


阅读 367

收藏
2020-07-07

共1个答案

一尘不染

实际上,您的代码应如下所示:

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);
    })
  });
}

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

资源:

http://nodejs.org/docs/latest/api/cluster.html
http://delicious.com/alessioaw/socket.io

2020-07-07