用RESTful体系结构进行长轮询(用户通知)

我正在做一个简单的RESTful api(在NodeJs上)。 我明白,宁静意味着水平缩放将会更容易。 不幸的是,我需要某种方式让客户几乎立即得到某些事件的通知。 为此,我正在考虑做长期投票。 我有这个问题是如何与多个服务器的工作。 例如,这是一个简化的用例:

Both servers A and B are behind a common load balancer. User Alice posts a message on Bob's wall (PUT request on server A). If Bob is online, he should be notified instantly (long-polling on server B). 

服务器A如何向Bob发送通知,或者服务器B知道应该通知Bob?

首先,我不知道为什么你不会在客户端和服务器上使用像socket.io东西来处理你的通知通道。 这将使用networking套接字(如果可用)(比长轮询更有效),然后如果没有networking套接字,则回退到长轮询。

有许多方法可以处理通知可能没有连接到发起通知的服务器的用户的问题:

连接数据库

当一个用户连接时,它们被平衡到一个随机的服务器,但是他们最终连接到的服务器被存储在一个中央数据库(例如,一个redis存储器)中,你的任何服务器都可以从中找出哪个服务器当前是哪个服务器连接到。 这使您能够查找任何用户当前连接到哪个服务器。 处理用户连接的每个服务器只是在用户连接时将每个用户添加到数据库,并引用其服务器标识,并在用户断开连接时将其从数据库中删除。 注意:由于这些信息不需要永久存储在磁盘上,而且数据量也很小,所以你可以select一个能够保存大部分或全部信息的数据库。

散列连接

基于用户的一些众所周知的特征,例如他们的用户ID,计算散列值,并且创build可重复的algorithm以在服务器池中映射散列值。 这是一个可预测的任务。 因此,当服务器想要通知Bob时,他们可以调用相同的函数来确定Bob连接到的服务器。 散列algorithm可以是自适应的,如果今天有三台服务器,则散列用户在三台服务器之间均匀分布,如果明天有四台服务器,散列用户将平均分布在四台服务器中。

多连接

由于低活动的Websocket现在可以很好的扩展,所有的用户都可以连接到所有的服务器,因此每个服务器都有一个与用户的套接字连接。 这是更简单的基础设施,但最终不是可扩展的。

长时间的投票方式给客户端造成了定期请求的负担 – 因此它们是单独的请求。 长时间轮询没有“通知客户”。 客户端民意调查。

您可以使用分布式caching来存储A和B都可以访问的中间状态信息。 因此,服务器A和B可以参与与客户机的对话,因为它全部保存在分布式caching中。

 Client Alpha Request 1 -> Node A =) Cache it as k,v (Aplha, State<-has request info) 

同时,一个或多个节点A,B,C或D在其上工作并占用自己的时间。

 Client Alpha Request 2 -> Node B =) Retrieve Cache it as k,v (Aplha,State <-not done) (are we done yet?) 

同时一个工作完成。 你的请求被履行:)即

节点X =)更新caching(Aplha,State < – 结果)

 Client Alpha Request 2 -> Node B =) Retrieve Cache it as k,v (Aplha, State<-results) (are we done yet?) (here you Sir - your results are now ready) 

WebSockets:另一个select是去WebSockets而不是长轮询

  Connection between Client and Node A is persistent with bidirectional communication.