Pub/Sub 服务概览

Pub/Sub 是一种发布/订阅publish/subscribe (publish/subscribePub/Sub) 服务,这是一种消息传递服务,其中消息的发送者与消息的接收者相分离。publish/subscribePub/Sub 服务中有几个关键概念,借助下图加以解释。

此图显示了 Pub/Sub 服务的不同组件以及它们如何彼此连接。
图 1 两个发布者客户端向同一 Pub/Sub 主题发送两条不同的消息。

以下是 Pub/Sub 服务的组件:

  • 发布者(也称为生产者):创建消息并将其发送(发布)到指定主题上的消息传递服务。

  • 消息:通过服务移动的数据。

  • 主题:代表消息源的命名实体。

  • 架构:控制 Pub/Sub 消息数据格式的命名实体。

  • 订阅:表示想要接收特定主题的消息的命名实体。

  • 订阅者(也称为使用方):通过指定订阅接收消息。

以下过程讨论了 Pub/Sub 服务的工作流:

  1. 两个发布商应用(发布商 1发布商 2)向单个 Pub/Sub 主题发送消息。发布商 1 发送消息 A发布商 2 发送消息 B

  2. 主题本身附加到了两个订阅。这两个指标分别为订阅 1订阅 2

  3. 主题还会附加到架构中。

  4. 每个订阅都会收到来自主题的 AB 消息的副本。

  5. 订阅 1 连接到两个订阅者应用:订阅者 1订阅者 2。这两个订阅者应用会从主题接收一部分消息。在此示例中,订阅者 1 接收消息 B订阅者 2 从主题接收消息 A

  6. “订阅 2”仅连接到名为“订阅者 3”的单个订阅者应用。因此,订阅者 3 会从主题接收所有消息。

Pub/Sub 中消息的生命周期

假设有一个发布者客户端连接到一个主题。该主题附加了单个订阅。单个订阅者连接到订阅。

显示消息在 Pub/Sub 中如何流动的图。
图 2 一条消息通过 Pub/Sub 从发布者客户端流向订阅者客户端。

以下步骤描述了消息在 Pub/Sub 中如何流动:

  1. 发布者应用向 Pub/Sub 主题发送消息。

  2. 消息写入到存储空间。

  3. 在将消息写入存储空间时,Pub/Sub 会将消息传递到该主题的所有附加订阅。

    在此示例中,它是单个订阅。

  4. 订阅将消息发送到附加的订阅者应用。

  5. 订阅者向 Pub/Sub 发送确认,表明他们已处理该消息。

    在每个订阅的至少一个订阅者确认消息后,Pub/Sub 会从存储空间中删除该消息。

Pub/Sub 中消息的状态

当向某个订阅者发送的消息未完成时,Pub/Sub 会尝试不将其传送给同一订阅的任何其他订阅者。订阅者必须在一段可配置的限定时间内(称为 ackDeadline)确认未完成的消息。该期限过后,该消息不再被视为未完成,Pub/Sub 将尝试重新传送该消息。

Pub/Sub 服务中的消息可能有三种状态:

  • 已确认的消息(已确认)。订阅者应用处理从主题发送到订阅的消息后,会将确认信息发回 Pub/Sub。如果某个主题上的所有订阅均已确认消息,则该消息将从发布消息来源和存储空间异步删除。

  • 未确认的消息(未确认)。如果 Pub/Sub 在确认时限内未收到确认,则可能会多次传送消息。例如,订阅者可能会在截止日期之后发送确认,或者确认可能会因暂时性网络问题而丢失。未确认的消息会持续传送,直到自消息发布后消息保留时长到期。此时,消息将过期。

  • 否定确认的消息(已 NACK)。订阅者 Nack 消息会导致 Pub/Sub 立即重新传送消息。当订阅者接收无效消息或无法处理消息时,订阅者可确保这些消息不会丢失,并最终得到成功处理。您可以使用值为 0 的 modifyAckDeadline 接收消息。

选择 Pub/Sub 发布和订阅模式

如果有多个发布者和订阅者客户端,您还必须选择要设置的发布和订阅架构的类型。

图显示了不同的发布和订阅模式。
图 3 发布商-订阅者关系可以是多对一(扇入)、多对多(负载均衡)和一对多(扇出)。

下面列出了一些受支持的 Pub/Sub 发布订阅模式:

  • 扇入(多对一)。在此示例中,多个发布者应用会向单个主题发布消息。这一个主题会附加到单个订阅。订阅继而连接到单个订阅者应用,该应用会从主题获取所有已发布的消息。

  • 负载均衡(多对多)。在此示例中,单个或多个发布者应用向单个主题发布消息。这个主题会附加到单个订阅,而该订阅又会连接到多个订阅者应用。每个订阅者应用都会获得一部分已发布消息,并且两个订阅者应用都不会获得同一子集的消息。在此负载均衡的情况下,您使用多个订阅者大规模处理消息。如果需要支持更多消息,您可以添加更多订阅者来接收来自同一订阅的消息。

  • 扇出(一对多)。在此示例中,一个或多个发布者应用会将消息发布到单个主题。这个主题会附加到多个订阅。每个订阅都连接到单个订阅者应用。每个订阅者应用都会从主题获得同一组已发布的消息。如果某个主题有多个订阅,则每条消息都必须发送给代表每个订阅接收消息的订阅者。如果您需要对同一组消息执行不同的数据操作,则扇出是一个不错的选择。您还可以为每个订阅附加多个订阅者,然后为每个订阅者获取经过负载均衡的消息子集。

选择 Pub/Sub 配置选项

您可以使用以下任一选项配置 Pub/Sub 环境:

  • Google Cloud 控制台
  • Google Cloud CLI
  • Cloud 客户端库(高级客户端库)
  • REST 和 RPC API(低级别客户端库)

具体选择哪个 Pub/Sub 配置选项取决于您的使用场景。

如果您刚开始接触 Google Cloud 控制台,并且希望测试 Pub/Sub,请使用控制台或 gcloud CLI

如果您需要高吞吐量、低延迟时间,同时尽可能减少运营开销和处理费用,则建议使用高级客户端库。默认情况下,高层级客户端库使用 StreamingPull API。 高级客户端库包含预构建的函数和类,用于处理身份验证、吞吐量和延迟时间优化、消息格式设置及其他功能的底层 API 调用。

低级别客户端库是一个自动生成的 gRPC 库,在您直接使用服务 API 时发挥作用。

以下是一些使用客户端库的最佳实践:

  • 选择合适的客户端库语言。Pub/Sub 客户端库的性能因语言而异。例如,与 Python 客户端库相比,Java 客户端库更有效地纵向扩容,并且可以处理更多吞吐量。 就处理发布或订阅负载所需的计算资源而言,Java、C++ 和 Go 是更高效的语言。

  • 使用最新版本的客户端库。Pub/Sub 客户端库会不断更新,以加入新功能和修复 bug。确保您使用的是适用于您所用语言的客户端库的最新版本。

  • 重复使用发布商客户端。发布消息时,重复使用同一发布者客户端比为每个发布请求创建新的发布者客户端效率更高。这是因为创建新的发布者客户端后的第一个发布请求需要一些时间来建立已获授权的连接。在某些没有显式发布者客户端的语言(例如 Node)中,请重复使用用于调用 publish 方法的对象。例如,在 Node 中,保存并重复使用主题对象。

如何设置 Pub/Sub

以下是配置 Pub/Sub 的顶级步骤:

  1. 创建或选择可以在其中设置 Pub/Sub 的 Google Cloud 项目。

  2. 启用 Pub/Sub API。

  3. 获取运行 Pub/Sub 所需的角色和权限。

  4. 创建主题。

  5. 如果消息结构至关重要,请为消息定义一个架构。

  6. 将架构附加到主题。

  7. 配置可以向主题发布消息的发布者客户端。

  8. 如果需要,请配置高级发布选项,例如流控制、批量消息传递和并发控制。

  9. 根据您所需的消息接收方式,选择订阅类型。

  10. 为所选主题创建订阅。

  11. 配置可接收来自订阅的消息的订阅者客户端。

  12. 如果需要,请配置高级消息传送选项,例如正好一次传送、租赁管理、订购传送和流控制。

  13. 开始从发布者客户端向该主题发布消息。

  14. 同时,将订阅者客户端设置为接收和处理这些消息。

主题、订阅、架构或快照的命名准则

Pub/Sub 资源名称唯一标识 Pub/Sub 资源(例如主题、订阅、架构或快照)。资源名称必须符合以下格式:

projects/project-identifier/collection/ID

  • project-identifier:必须是可从 Google Cloud 控制台获得的项目 ID 或项目编号。例如,my-cool-project 是项目 ID。 123456789123 是项目编号。

  • collection:必须是 topicssubscriptionsschemassnapshots 中的一个。

  • ID:必须符合以下准则:

    • 不以字符串 goog 开头
    • 以字母开头
    • 包含 3 到 255 个字符
    • 仅包含以下字符:字母 [A-Za-z]、数字 [0-9]、短划线 -、下划线 _、句点 .、波浪线 ~、加号 + 和百分号 %

    您可以在不进行网址编码的资源名称中使用上述列表中的特殊字符。不过,在网址中使用任何其他特殊字符时,您必须确保对其进行正确编码或解码。例如,mi-tópico 是无效的 ID。不过,mi-t%C3%B3pico 是有效的。当您进行 REST 调用时,此格式非常重要。

后续步骤