GCP PubSub - 广播消息 - 只有相关订阅者处理消息

qui*_*tin 1 broadcast google-cloud-pubsub

我在负载均衡环境中使用 GCP PubSub 作为 Web Sockets 的后端。当前的实现为负载均衡器后面的每个服务器都有一个主题以及最终用户和服务器之间的映射。当我希望向特定用户发送消息时,我使用映射来确定将其发布到哪个主题。

这是可行的,但它有很多移动部件,并且需要在通过缩小规模或推出应用程序的更新版本来删除服务器时清理主题。

我现在正在探索一种更复杂的实现,其中只有一个主题。由于每个服务器都知道其最终用户,理论上我可以向这个单一主题发布消息,并且每个服务器都可以检查该消息,将其与其用户列表进行比较。只有当前具有消息中指定的最终用户的 Web Socket 连接的服务器才会处理它。

这让我想到了我的问题 - 如何使用 PubSub 实现这一目标?

  • 目前我正在使用拉取订阅,我是否需要使用推送订阅?也许这将允许同时交付给所有订阅者?
  • 在 Pull 模型中,如果订阅者没有.ack()消息,可能会允许重新传递消息,但消息可能需要很长时间才能最终发送到适当的订阅者(违背了 Web Sockets 的目的,是“实时”更新) - 这是对其在请求订阅模型中如何工作的公平评估吗?
  • 我是否使用了错误的工具来完成这项工作?这是可能的,但我希望我只需要以不同的方式使用当前的工具

gui*_*ere 5

在这种情况下,我将使用这种设计:

  • 只创建一个主题,所有消息都发布在其中
  • 当 VM 启动时,VM 会为自己创建 PubSub 主题的请求订阅
  • 当虚拟机关闭时,虚拟机会删除订阅(例如在关闭脚本中)

然后,当一条消息到达时,它仅发布在一个 PubSub 主题中,并散布到所有活动订阅。VM 不断拉取消息。当消息到达拉取队列时:

  • VM检查是否适合它
    • 如果不是,则确认该消息(将其从订阅中删除,而不是其他订阅)
    • 如果是,则处理并确认消息

通过这一设计,您可以最大限度地减少延迟,并且只需在一个主题中进行发布。但是,您会复制大量消息,并且会消耗处理能力来丢弃所有不相关的消息。


编辑1

原理如下:您在主题中发布 1 条消息,然后该消息在所有订阅中重复,并且订阅者(每个订阅 1 个或多个)收到 1 个订阅的消息的子集(如果只有订阅则为所有消息) 1 位订阅者)

这就是为什么,在我的建议中:

  • 每个虚拟机创建自己的订阅,并且是其上唯一接收主题中发布的所有消息的副本的订阅者。
  • 不相关的消息被确认以将其从队列中删除。它们只会从当前 VM 的当前订阅中删除。