Pub/Sub 服务概览

Pub/Sub 是一种发布/订阅 (Pub/Sub) 服务,即消息的发送者与消息的接收者分离的消息传递服务。Pub/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 仅与一个名为 Subscriber 3 的订阅方应用相关联。因此,订阅者 3 会接收该主题中的所有消息。

消息的生命周期

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

显示消息如何在 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 服务中的消息可以有三种状态:

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

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

  • 收到了负确认消息 (nacked)。订阅者对消息进行 Nack 会导致 Pub/Sub 立即重新传送该消息。当订阅者拒收无效的消息或无法处理消息时,订阅者有助于确保这些消息不会丢失,并最终会成功处理。您可以使用值为 0 的 modifyAckDeadline 来 nack 消息。

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

如果有多个 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. 创建或选择一个 Google Cloud 项目,以便在其中设置 Pub/Sub。

  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 调用时,此格式非常重要。

后续步骤