如何在没有redis的情况下缩放socket.io

我目前正在寻找一个替代scheme来扩展我的快递应用与socket.io。 问题是我不想使用redis作为socket.io存储。 除了Clusterhub之外,是否还有其他的可能性来对socket.io进行集群?

编辑:我试图使用fakeredis作为redis的替代品,但它似乎不适用于socket.io。 从ActionHero.js我知道,faye-websocket与fakeredis一起工作。

这很可能取决于您的socket.io使用情况以及要实现的扩展types(群集与扩展到多台机器)。

所以,这是我做了什么来扩展我们使用socket.io到多个服务器。

我们在负载均衡器后面有3个服务器,当一个套接字连接它连接到3个服务器中的任何一个时,三个服务器有一个内存中的套接字列表,并且这三个服务器有一个内部服务器地址的命令列表,例如[server1, server2,server3]。

我所做的基本上是一个戒指(在内部我们称之为“戒指”):

  • 如果我需要从server1发送一个事件到一个套接字,我首先查看套接字是否连接到server1,如果不是,我发送一个http请求到下一个服务器(server2),它将检查套接字是否在那里,如果没有在那里它会发送相同的请求到server3,依此类推,直到到达原点,在这种情况下,你可能会抛出一个错误。
  • 如果我需要广播一条消息,它几乎是一样的,我从一台服务器开始,然后在另一台服务器上调用一个http端点。

我用来确定下一个节点(next_node.js)的algorithm是:

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; }; 

注意事项:

  • 这些服务器和networking分区之间的延迟时间很低,不太可能,它们在物理上位于同一个数据中心。 但是如果是networking分区对我们来说并不重要。
  • 我们总是在同一个方向运行戒指。 一个改进的版本将运行在两个方向(?)
  • 服务器共享一个秘密来调用这些端点。

在我看来,这是一个非常简单的方法来实现扩展在很多socket.io使用情况下,可能有很多其他情况下,这不是一个选项,但我希望这给一些想法。

如果您对Azure服务感到满意,那么Azure团队中的一些人已经可以自由地为socket.io编写服务总线存储 。

Glenn Block解释了服务总线上的Socket.IO横向扩展