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

Posted

技术标签:

【中文标题】node.js + socket.io + redis 架构 - 水平服务器缩放套接字连接?【英文标题】:node.js + socket.io + redis architecture - horizontal serverscaling socket connections? 【发布时间】:2013-07-25 02:12:55 【问题描述】:

我是第一次使用 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连接(sockets)会在Server AServer B上存储和管理。

示例场景:

用户 A 连接到 服务器 A用户 B 连接到 服务器 B。这意味着,用户 A 在服务器 A 上拥有一个套接字,而用户 B 在服务器 B 上拥有一个套接字。

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

非常感谢!

【问题讨论】:

【参考方案1】:

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

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

【讨论】:

@elchueko 你能举个例子你是怎么用redis解决的吗?【参考方案2】:

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

【讨论】:

以上是关于node.js + socket.io + redis 架构 - 水平服务器缩放套接字连接?的主要内容,如果未能解决你的问题,请参考以下文章

Node.js - Socket.io:socket.request 未定义

HTTP 状态代码 200 但页面未加载 Node.js Socket.io -- 使用 Socket.io 的 Node.js 教程,Daniel Nill,fs.readFile(),socket

Node.js 和 socket.io 的混淆

Node.js socket.io.js 未找到或 io 未定义

找不到Node.js /socket.io/socket.io.js express 4.0

node.js + socket.io:拍卖网站开发