node.js + socket.io + redis架构 - 水平服务器缩放套接字连接?

时间:2013-07-25 09:11:33

标签: node.js express redis socket.io scalability

我第一次使用node.js并希望得到一个建议:

我在我的服务器上安装了以下程序:

  • node.js v0.11.3-pre
  • express v3.3.4
  • socket.io v0.9.14
  • connect-redis v1.4.5
  • Redis服务器v = 2.6.14
  • redis-cli 2.6.14

首先,我创建了一个快速应用程序:

express testApplication

在创建的“package.json”中,我定义了所有必要的依赖项。

从一开始,我就在一个名为“cluster.js”的文件中定义了一个用于垂直扩展(多进程)的集群:

var cluster = require('cluster');

if( cluster.isMaster ) {
        var noOfWorkers = process.env.NODE_WORKERS || require('os').cpus().length;

        console.log("Workers found: " + noOfWorkers);

        for (var i = 0; i < noOfWorkers; i += 1) {
                cluster.fork();
        }
} else {
        require('./app.js');
}

cluster.on('exit', function(worker, code, signal) {
        var exitCode = worker.process.exitCode;

        console.log('worker' + worker.process.pid + ' died (' + exitCode + '). restarting...');

        if( typeof cluster.workers[worker.id] != "undefined" )
                cluster.workers[worker.id].delete();

        cluster.fork();
});

在我的“app.js”文件中,我为socket.io存储定义了REDIS:

  io.set('store', new RedisStore({
            redisPub: pub,
            redisSub: sub,
            redisClient: client
          }));

到目前为止,这么好,这一切都很好。

当客户端连接到socket.io服务器时,群集将处理与不同工作者的连接。

我的意图是,客户端可以向特定的另一个客户端发送消息,因此socket.io服务器必须从接收者中找到套接字才能仅向该用户发送消息。我的解决方案是,我为数组中的每个用户存储所有创建的套接字ID,当发送消息时,我在数组中选择相关的套接字id,通过id获取套接字,并将消息发送到套接字(s )。

这适用于仅在一台服务器上运行的socket.io应用程序。 现在,我想配置另一台具有相同程序,模块和软件包的服务器。 负载平衡可能由 HAProxy 处理。因此,socket.io连接(套接字)将在服务器A 服务器B 上存储和管理。

示例方案:

用户A 连接到服务器A 用户B 连接到服务器B 。这意味着,用户A在服务器A上具有套接字,在服务器B上具有用户B.

应用程序知道,它必须在服务器B上查找用户B的套接字才能发送消息吗?在服务器A上,它找不到套接字,因为它是在服务器B上创建的。

很多!

2 个答案:

答案 0 :(得分:5)

当您横向扩展时,您需要在服务器之间共享数据存储。方便的是,你已经有一个理想的,就是Redis。您需要将其插入Redis,并从那里进行查找,而不是将套接字映射保留在数组中。

然后,您可以决定让服务器相互发送消息,或者更可靠地通过Redis发送消息。因此,每个服务器都会在Redis上查看它的队列,以查看它应该向哪些套接字发送的消息。当服务器收到消息时,它会将其推送到Redis,并发送给应该提供它的服务器。如果消息的排序对您很重要,我建议您在Redis上查看https://github.com/learnboost/kue层。

答案 1 :(得分:0)

别忘了在NodeJS之前加入NGINX并使用PM2!