水平扩展在服务器之间共享输入的应用程序

时间:2014-01-14 13:34:01

标签: node.js rabbitmq scalability latency

我正在构建一个通过websocket接受输入的应用程序,该websocket必须共享回可能连接到其他前端服务器的其他客户端。

为简单起见,想象一下多用户多房间聊天应用程序。将输入路由到正确的连接不是问题,它是服务器之间的消息传递,并且能够扩展它并保持消息的延迟得到控制。

现在我有一个每个前端连接的代理进程,然后他们订阅一个队列,以获取其连接可能需要了解的任何内容。这样做是为了切断来自代理的接收消息,这些消息永远不会被前端使用。但是,我仍然得到大约75%到85%的消息从代理发送回每个前端。

我正在进行消息验证,解析和任何其他业务逻辑工作。在旅行中,我循环遍历订阅的本地数组并将消息发送到每个订阅的连接。

一个例子:如果我在11个前端服务器上收到10封邮件(总共110条消息 - 本地处理10条消息而不是代理发回)* 0.75乐观订阅级别= 75条消息被发送回每个服务器要处理。因此,每个服务器在这段时间内处理了10个本地+75个代理= 85条消息。

现在我不会有100个msg / sec的11个前端服务器,可能是两个,但是代理进程发送回每个前端服务器的消息似乎会爆炸我在其他前端服务器上收到的消息越多。

代理进程是一个与RabbitMQ和PostgreSQL对话的小型node.js应用程序。前端服务器也是node.js应用程序。

在高音量期间,我能做些什么或者我应该做些什么来保持低延迟?

更新以回复用户评论:虽然我希望队列之间有很多重叠,但是连接会导致他们的前端服务器订阅我不希望每个服务器都是100%。最糟糕的情况是每个前端服务器必须订阅代理上的每个队列,从而从代理获得100%的消息。乐观地说,只有大约75%的消息确实需要发送回任何特定的前端服务器。

itaifrenkel的第二次更新:两个用户发送的消息可能会以不同的顺序返回。只有当延迟非常低并且仅在消息彼此非常接近时才会发生,这是可以接受的。如果发生了几秒钟的消息,那么我会说我们遇到延迟和规模问题。

有一种情况我们需要显示历史记录,但我将其遗漏了,因为我觉得这不属于问题的范围。

2 个答案:

答案 0 :(得分:0)

消息队列解决方案听起来像是正确的选项。正如你在标题中所建议的那样,为了扩展它,你需要走向水平。

我没有使用过RabbitMQ,所以我不能用细节来打扰你,但水平扩展意味着一个集群,所以http://www.rabbitmq.com/clustering.html可能足以让你前进。

答案 1 :(得分:0)

假设每个用户在任何时候只连接到一个聊天室。这意味着一个websocket连接=一个聊天室。因此,您可以编写一个额外的node.js反向代理,它将每个用户连接转发到“前端”node.js进程,该进程很可能已经在侦听该聊天室的事件(使用基于协同散列的一致哈希的聊天室亲缘关系)聊天室)。这种路由算法需要尽最大努力来提高网络利用率,它不需要是完美的。

现在让我们允许每个用户进入多个聊天室。然后,您需要改进反向代理以连接到多个“前端”服务器,并将结果多路复用回用户。

此设计将以网络延迟为代价提供水平可扩展性。

注意:当然新的反向代理现在是前端服务器,但是当我提到“前端”时,我会引用你在问题中描述的服务器。