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 A和Server 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.js 未找到或 io 未定义