我目前正在寻找一种替代方案来使用 socket.io 扩展我的 Express 应用程序。问题是我不想使用 redis 作为 socket.io 存储。除了使用之外,是否还有其他可能性来集群 socket.io集群集线器 https://github.com/fent/clusterhub?
编辑:我尝试使用法雷迪斯 https://github.com/hdachev/fakeredis作为redis的替代品,但它似乎不适用于socket.io。从ActionHero.js https://github.com/evantahler/actionhero我知道 faye-websocket 可以与 fakeredis 配合使用。
这很可能取决于您的 socket.io 使用情况以及您想要实现的扩展类型(集群与扩展到多台机器)。
因此,我所做的就是将 socket.io 的使用扩展到多个服务器。
我们在负载均衡器后面有 3 个服务器,当套接字连接时,它会连接到 3 个服务器中的任何一个,这三个服务器在内存中具有套接字列表,并且三个服务器具有内部服务器地址的顺序列表,例如[服务器1、服务器2、服务器3]。
我所做的基本上是一个环(内部我们称之为“套接字环”):
- 如果我需要从 server1 向套接字发出事件,我首先查看套接字是否连接到该 server1,如果没有,我将向下一个服务器(server2)发送 http 请求,该服务器将检查套接字是否存在,如果不存在在那里它将向 server3 发送相同的请求,依此类推,直到到达原点,在这种情况下您可能会抛出错误。
- 如果我需要广播消息,它几乎是相同的,我从一台服务器开始,然后调用其他服务器上的 http 端点。
我用来确定下一个节点(next_node.js)的算法是:
var nodes = process.env.NODES.split(',');
//this is usually: http://server1/,http://server2/,http://server3/
var url = require('url');
var current = require("os").hostname();
//origin is the node that started the lookup
exports.get = function (origin) {
var next_node_i = nodes.map(function (uri) {
return url.parse(uri).hostname;
}).reduce(function (prev, curr, i, arr){
return curr === current && i < arr.length - 1 ? i + 1 : prev;
}, 0);
var next_node = nodes[next_node_i];
if (origin && url.parse(next_node).hostname === origin) {
// if the next node is equal to the first node initiating the lookup
// it means the socket we are looking for is not connect to any node.
return null;
}
return next_node;
};
Caveats:
- 这些服务器之间的延迟很低,并且网络分区不太可能,它们物理上位于同一数据中心。但如果是网络分区对我们来说就没那么重要了。
- 我们总是朝同一个方向跑环。改进的版本将是双向运行(?)
- 服务器共享一个秘密来调用这些端点。
在我看来,这是在许多 socket.io 用例中实现扩展的一种非常简单的方法,可能在很多其他场景中这不是一个选项,但我希望这能提供一些想法。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)