如何创建具有多个工作人员的队列?

时间:2012-06-28 15:37:47

标签: firebase

我想创建一个客户端可以放入请求的队列,然后服务器工作线程可以将它们拉出来,因为它们有可用的资源。

我正在探索如何使用Firebase存储库,而不是外部队列服务,然后必须将数据注入Firebase。

考虑到安全性和验证工具,以下是我想到的一个简单示例:

  • 用户将请求推送到“队列”存储桶
  • 服务器提取请求并将其删除(如何确保只有一台服务器获取请求?
  • 服务器验证数据并从私有存储桶中检索(或注入新数据)
  • 服务器将数据和/或错误推送回用户的存储桶

enter image description here

这可能有用的简化示例是身份验证:

  • 用户将身份验证请求放入公共队列
  • 他的登录名/密码进入他的私人桶(只有他可以读/写的地方)
  • 服务器获取身份验证请求,检索登录名/密码,并仅对服务器可以访问的私有存储桶进行验证
  • 服务器将令牌推送到用户的私人存储桶

(当然公共队列中仍然存在一些安全漏洞;我现在只是在探索)

其他一些使用示例:

  • 只读状态队列(用户状态通过私有桶传送,服务器写入公共桶,对公众只读)
  • 消息队列(消息通过用户发送,服务器决定丢弃哪些讨论桶)

所以问题是:

  1. 这是一个很好的设计,能够很好地融入即将到来的安全计划吗?有哪些替代方法正在探索中?
  2. 如何让所有服务器都收听队列,但只有一个服务器来接收每个请求?

2 个答案:

答案 0 :(得分:8)

哇,好问题。这是我们内部讨论的使用模式,因此我们很乐意听到您实施它的经验(support@firebase.com)。以下是您对问题的一些看法:

<强>验证

如果您的主要目标是实际身份验证,请等待我们的安全功能。 :-)特别是,我们打算能够通过您自己的后端服务器进行身份验证,由firebase用户存储支持,或者由第三方提供商(Facebook,Twitter等)支持。

负载均衡的工作队列

无论auth如何,使用Firebase作为您描述的某种工作负载平衡系统的主干仍然是一个有趣的用例。为此,您可以采取几种方法:

  1. 如您所述,拥有一个工作队列,您的所有服务器都会监视并从中删除项目。您可以使用transaction()删除项目来完成此操作。 transaction()处理冲突,以便只有一个服务器的事务成功。如果一个服务器将第二个服务器击败到工作项,则第二个服务器可以中止其事务并再次尝试队列中的下一个项目。这种方法很好,因为它会在您添加和删除服务器时自动扩展,但是每次事务尝试都会产生开销,因为它必须对firebase服务器进行往返,以确保没有其他人已经从队列中抓取该项目。但是,如果处理工作项所花费的时间远远大于到Firebase服务器的往返时间,那么这个开销可能不是什么大问题。如果你有很多服务器(即更多的争用)和/或许多小工作项,那么开销可能是一个杀手。
  2. 通过让负载均衡在多个工作队列中随机选择,将负载均衡推送到客户端。 (例如,拥有/ queue / 0,/ queue / 1,/ queue / 2,/ queue / 3,并让客户端随机选择一个)。然后,每个服务器可以监视一个工作队列并拥有所有处理。通常,这将具有最小的开销,但是当您添加/删除服务器时它无法无缝扩展(您可能需要保留服务器在联机时更新的单独工作队列列表,然后拥有客户端监控列表,以便他们知道有多少队列可供选择等。)。
  3. 就个人而言,如果你想要最佳性能,我会倾向于选项#2。但#1可能更容易进行原型设计,并且至少在最初阶段就可以了。

    一般来说,您的设计肯定是在正确的轨道上。如果您尝试实施并遇到问题或对我们的API提出建议,请告诉我们(support@firebase.com: - )!

答案 1 :(得分:3)

这个问题已经很老了,但万一有人在这里问了......

自2015年中期以来,Firebase提供了一种名为Firebase Queue的功能,这是一种基于Firebase构建的容错多工作者管道。

  

问:这是一个很好的设计,能够很好地融入即将到来的安全计划吗?

答:您的设计建议与Firebase队列完全吻合。

  

问:如何让所有服务器都收听队列,但只有一个服务器可以接收每个请求?

答:嗯,这几乎就是Firebase Queue为您所做的事情!

参考文献: