node.js + socket.io + redis 架构 - 如何水平扩展socket连接?

5
我第一次使用Node.js,希望得到一些建议:
我在服务器上安装了以下程序:
  • Node.js v0.11.3-pre
  • Express v3.3.4
  • Socket.io v0.9.14
  • Connect-redis v1.4.5
  • Redis server v=2.6.14
  • Redis-cli 2.6.14
首先,我创建了一个Express应用程序:
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”文件中,我定义了REDIS用于存储socket.io的数据:
  io.set('store', new RedisStore({
            redisPub: pub,
            redisSub: sub,
            redisClient: client
          }));

到目前为止,一切都很顺利,所有功能都能正常运行。当客户端连接到socket.io服务器时,集群会使用不同的工作进程处理连接。我的意图是让客户端能够向特定的另一个客户端发送消息,因此socket.io服务器必须找到接收方的套接字,只向该用户发送消息。对我来说,解决方案是将每个用户的所有创建的套接字ID存储在数组中,发送消息时,从数组中选择相关的套接字ID,通过ID获取套接字,并将消息发送到套接字(s)。这对于仅在一个服务器上运行的socket.io应用程序非常有效。现在,我想使用相同的程序、模块和包配置另一个服务器。负载平衡可能由HAProxy处理。因此,socket.io连接(套接字)将存储和管理在Server A和Server B上。例如:User A连接到Server A,User B连接到Server B。这意味着User A在Server A上有一个套接字,而User B在Server B上有一个套接字。如何使应用程序知道它必须查找Server B上User B的套接字以发送消息?在Server A上,它找不到套接字,因为它是在Server B上创建的。谢谢!
2个回答

6

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

然后,你可以决定让服务器相互发送消息,或者更具可伸缩性地,也可以通过Redis发送消息。因此,每个服务器都会查看其在Redis上的队列,以查看它应该向哪些套接字发送消息。当服务器收到消息时,它将把它推入Redis,寻址给应该传递它的服务器。如果消息的顺序对你很重要,我建议在Redis之上使用https://github.com/learnboost/kue


@elchueko,你能否发布一个使用Redis解决问题的示例? - patrick

0

别忘了在 NodeJS 前面加上 NGINX 并使用 PM2!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接