GCP PubSub - 广播消息 - 只有相关订阅者处理消息
GCP PubSub - broadcast message - only relevant subscriber handles message
我在负载均衡环境中使用 GCP PubSub 作为 Web 套接字的后端。当前的实现为负载均衡器后面的每个服务器都有一个主题,并且在最终用户和服务器之间有一个映射。当我希望向特定用户发送消息时,我使用映射来确定将消息发布到哪个主题。
这可行,但它有很多移动部分,并且需要在通过缩小规模或推出更新版本的应用程序删除服务器时清理主题。
我现在正在探索一种更复杂的实现方式,其中只有一个主题。由于每个服务器都知道它的最终用户,理论上我可以向这个主题发布一条消息,每个服务器都可以检查该消息,并将其与它的用户列表进行比较。只有当前具有消息中指定的最终用户的 Web 套接字连接的服务器才会处理它。
这让我想到了我的问题 - 如何使用 PubSub 实现这一目标?
- 目前我使用的是请求订阅,是否需要使用推送订阅?也许这样可以同时向所有订阅者发送内容?
- 在 Pull 模型中,如果订阅者没有
.ack()
消息,大概允许重新传递消息,但消息最终可能需要很长时间才能发送到适当的位置订阅者(破坏了 Web Sockets 的目的,即“实时”更新)——这是对它在 Pull 订阅模型中如何工作的公平评估吗?
- 我是否使用了错误的工具来完成这项工作?这是可能的,但我希望我只需要对当前工具进行不同的使用
在这种情况下,我将使用这种设计:
- 只创建一个发布所有消息的主题
- VM 启动时,VM 会为自己创建对 PubSub 主题的请求订阅
- 当 VM 关闭时,VM 删除订阅(例如在关闭脚本中)
然后,当一条消息到达时,它只发布在一个 PubSub 主题中,并散布到所有活动订阅中。 VM 不断拉取消息。当消息到达拉取队列时:
- VM检查是否适合它
- 如果否,请确认消息(将其从订阅中删除,而不是其他订阅)
- 如果是,处理并确认消息
通过这种设计,您可以最大限度地减少延迟,并且只在一个主题中发布。但是,您复制了很多消息并且消耗了处理能力来丢弃所有不相关的消息。
编辑 1
原理是这样的:你在主题中发布了1条消息,然后这条消息在所有订阅中被复制,订阅者(每个订阅1个或多个)收到1个订阅(或所有订阅者)的消息子集消息(如果订阅中只有 1 个订阅者)
这就是为什么,在我的提议中:
- 每个 VM 创建自己的订阅,并且是其上唯一一个接收主题中发布的所有消息副本的订阅者。
- 不相关的消息被确认将它们从队列中移除。它们仅从当前 VM 的当前订阅中删除。
我在负载均衡环境中使用 GCP PubSub 作为 Web 套接字的后端。当前的实现为负载均衡器后面的每个服务器都有一个主题,并且在最终用户和服务器之间有一个映射。当我希望向特定用户发送消息时,我使用映射来确定将消息发布到哪个主题。
这可行,但它有很多移动部分,并且需要在通过缩小规模或推出更新版本的应用程序删除服务器时清理主题。
我现在正在探索一种更复杂的实现方式,其中只有一个主题。由于每个服务器都知道它的最终用户,理论上我可以向这个主题发布一条消息,每个服务器都可以检查该消息,并将其与它的用户列表进行比较。只有当前具有消息中指定的最终用户的 Web 套接字连接的服务器才会处理它。
这让我想到了我的问题 - 如何使用 PubSub 实现这一目标?
- 目前我使用的是请求订阅,是否需要使用推送订阅?也许这样可以同时向所有订阅者发送内容?
- 在 Pull 模型中,如果订阅者没有
.ack()
消息,大概允许重新传递消息,但消息最终可能需要很长时间才能发送到适当的位置订阅者(破坏了 Web Sockets 的目的,即“实时”更新)——这是对它在 Pull 订阅模型中如何工作的公平评估吗? - 我是否使用了错误的工具来完成这项工作?这是可能的,但我希望我只需要对当前工具进行不同的使用
在这种情况下,我将使用这种设计:
- 只创建一个发布所有消息的主题
- VM 启动时,VM 会为自己创建对 PubSub 主题的请求订阅
- 当 VM 关闭时,VM 删除订阅(例如在关闭脚本中)
然后,当一条消息到达时,它只发布在一个 PubSub 主题中,并散布到所有活动订阅中。 VM 不断拉取消息。当消息到达拉取队列时:
- VM检查是否适合它
- 如果否,请确认消息(将其从订阅中删除,而不是其他订阅)
- 如果是,处理并确认消息
通过这种设计,您可以最大限度地减少延迟,并且只在一个主题中发布。但是,您复制了很多消息并且消耗了处理能力来丢弃所有不相关的消息。
编辑 1
原理是这样的:你在主题中发布了1条消息,然后这条消息在所有订阅中被复制,订阅者(每个订阅1个或多个)收到1个订阅(或所有订阅者)的消息子集消息(如果订阅中只有 1 个订阅者)
这就是为什么,在我的提议中:
- 每个 VM 创建自己的订阅,并且是其上唯一一个接收主题中发布的所有消息副本的订阅者。
- 不相关的消息被确认将它们从队列中移除。它们仅从当前 VM 的当前订阅中删除。