本文档简要介绍了不同类型的订阅在 Pub/Sub 中的工作原理。
订阅概览
如需接收发布到某个主题的消息,您必须创建对该主题的订阅。只有订阅创建后发布到该主题的消息才可供订阅者客户端使用。不过,您也可以启用主题保留,以允许附加到主题的订阅回溯并重放以前发布的消息。订阅者客户端接收并处理发布到该主题的消息。一个主题可以有多个订阅,但给定订阅属于单个主题。
订阅工作流
向订阅者发送消息后,订阅者必须确认消息。
如果消息被发送进行传递并且订阅者尚未确认消息,则该消息称为未完成。
Pub/Sub 反复尝试传送任何尚未确认的消息。但是,Pub/Sub 会尝试不向同一订阅的任何其他订阅者传送未完成的消息。
订阅者可配置一段限定的时间(称为
ackDeadline
),用于确认未完成的消息。该期限过后,该消息不再被视为未完成,并且 Pub/Sub 会尝试重新传送该消息。
订阅类型
创建订阅时,您必须指定消息传送类型。Pub/Sub 提供三种类型的消息传送,分别对应于以下三种类型的订阅。本文档的后续部分简要介绍了每种类型的订阅。
- 拉取订阅
- 推送订阅
- BigQuery 订阅
您可以随时更新订阅类型。
拉取订阅
对于拉取订阅,订阅者客户端会向 Pub/Sub 服务器发起请求来检索消息。订阅者客户端使用 REST Pull
API、RPC PullRequest
API、REST StreamingPullRequest
API 或 RPC StreamingPullRequest
API。大多数订阅者客户端不会直接发出这些请求。相反,客户端依赖于 Google Cloud 提供的高级别客户端库,该库在内部执行流式拉取请求并以异步方式传递消息。对于需要更好地控制消息拉取方式的订阅者客户端,Pub/Sub 会使用低级别的自动生成的 gRPC 库。此库会直接发出拉取或流式拉取请求。这些请求可以是同步请求,也可以是异步请求。
以下两张图片显示了订阅者客户端与拉取订阅之间的工作流。


拉取工作流如下所示,并引用图 1:
订阅者客户端显式调用拉取方法,该方法会请求传送消息。此请求是如下图所示的 PullRequest。
Pub/Sub 服务器返回零个或多个消息和确认 ID。没有消息或包含错误的响应未必表示没有可接收的消息。此响应是如下图所示的 PullResponse。
订阅者客户端显式调用已确认的方法。客户端使用返回的确认 ID 来确认消息已处理,无需再次传送。此请求是如下图所示的 AckRequest。
对于单个流式传输拉取请求,订阅者客户端可能会因开放连接而返回多个响应。相反,每个拉取请求仅返回一个响应。
如需详细了解拉取订阅的工作原理和配置示例,请参阅拉取订阅。
推送订阅
在推送订阅中,Pub/Sub 服务器向订阅者客户端发起请求以传递消息。
下图显示了订阅者客户端和推送订阅之间的工作流。

以下是引用图 3 的工作流的简要说明:
Pub/Sub 服务器将每条消息作为 HTTPS 请求发送到预配置端点上的订阅者客户端。此请求在图片中显示为 PushRequest。
端点通过返回 HTTP 成功状态代码来确认消息。如果响应不成功,则表示 Pub/Sub 必须重新发送消息。此响应在图片中显示为 PushResponse。
Pub/Sub 会根据其收到成功响应的速率动态调整推送请求的速率。
如需详细了解推送订阅的工作原理以及配置示例,请参阅推送订阅。
BigQuery 订阅
收到消息后,BigQuery 订阅会将消息写入现有 BigQuery 表。您无需配置单独的订阅者客户端。
如果没有 BigQuery 订阅类型,您需要一个拉取或推送订阅以及一个订阅者(例如 Dataflow)来读取消息并将其写入 BigQuery 表。如果消息在将消息存储在 BigQuery 表中之前不需要额外的处理,则无需运行 Dataflow 作业;您可以改用 BigQuery 订阅。不过,对于要求先进行一些数据转换才能将数据存储在 BigQuery 表中的 Pub/Sub 系统,我们仍然推荐使用 Dataflow 流水线。如需了解如何使用 Dataflow 将数据从 Pub/Sub 流式传输到 BigQuery,请参阅从 Pub/Sub 流式传输到 BigQuery。
下图显示了 BigQuery 订阅和 BigQuery 之间的工作流。

以下是引用图 4 的工作流的简要说明:
- Pub/Sub 使用 BigQuery Storage write API 将数据发送到 BigQuery 表。
- 这些消息会批量发送到 BigQuery 表。
- 写入操作成功完成后,该 API 会返回 OK 响应。
- 如果写入操作中存在任何失败情况,系统将否定确认 Pub/Sub 消息本身。然后,系统会重新发送此消息。如果消息失败的次数足够多,并且订阅上配置了死信主题,则该消息会移到死信主题。
如需详细了解 BigQuery 订阅的工作原理,请参阅 BigQuery 订阅。
确定订阅类型
下表就如何为您的应用选择合适的交付机制提供了一些指导:
拉取 | 推送 | BigQuery | |
---|---|---|---|
用例 |
|
|
|
端点 | 互联网上具有授权凭据的任何设备都可以调用 Pub/Sub API。 | HTTPS 服务器,具有可在公共网页上访问的非自签名证书。接收端点可以与 Pub/Sub 订阅分离,因此来自多个订阅的消息可以发送到单个端点。 | BigQuery 表格。 |
负载平衡 | 多个订阅者可以对同一个“共享”订阅进行拉取调用。每个订阅者都会接收消息的子集。 | 推送端点可以是负载均衡器。 | Pub/Sub 服务会自动平衡负载。 |
配置 | 不需要进行配置。 | 对于与订阅者属于同一项目的 App Engine 应用,无需进行任何配置。 Google Cloud 控制台中不需要验证推送端点。端点必须使用 DNS 名称进行访问,并已安装 SSL 证书。 |
主题订阅必须有 BigQuery 表。 |
流控制 | 订阅者客户端控制传送速率。订阅者可以动态修改确认时限,从而允许将消息处理设为任意时长。 | Pub/Sub 服务器自动实施流控制。无需在客户端处理消息流。但是,通过传回 HTTP 错误可以指示客户端无法处理当前消息加载。 | Pub/Sub 服务器自动实现流控制,以优化向 BigQuery 写入消息的操作。 |
效率和吞吐量 | 通过批量传送和确认以及大规模并行使用,在低 CPU 和带宽下实现高吞吐量。如果使用积极的轮询来最大限度地缩短消息传送时间,可能效率低下。 | 每个请求传送一条消息,并限制未完成消息的最大数量。 | 可伸缩性由 Pub/Sub 服务器动态处理。 |
默认订阅属性
默认情况下,Pub/Sub 提供至少一次传送,但不保证适用于所有订阅类型。或者,如果消息具有相同的排序键并位于同一区域,则可以启用消息排序。设置消息排序属性后,Pub/Sub 服务会按照相同的排序键以及 Pub/Sub 服务接收消息的顺序传送消息。
Pub/Sub 还支持在预览模式下使用正好一次传送。
通常,Pub/Sub 会按照消息的发布顺序传送每条消息。但是,消息有时可能会不按顺序或多次传送。即使针对消息的确认请求成功返回,Pub/Sub 也可能会重新传送消息。这种重新传送可能是由服务器端重启或客户端问题等问题导致的。因此,尽管极少数情况,我们也可以随时重新提交邮件。 为了适应多次传送,订阅者需要在处理消息时遵循幂等原则。
订阅到期
默认情况下,订阅会在订阅者处于不活跃状态 31 天后到期,或者如果订阅没有更新,订阅会过期。订阅者活动的示例包括打开连接、主动拉取或成功推送。如果 Pub/Sub 检测到订阅者活动或订阅属性更新,则订阅删除时钟会重启。使用订阅到期政策,您可以配置不活动时长,或者使订阅成为永久性订阅,而无论其活动情况如何。您也可以手动删除订阅。
虽然您可以创建名称与已删除订阅相同的新订阅,但新订阅与旧订阅没有任何关系。即使已删除的订阅包含许多未确认的消息,使用相同名称创建的新订阅在创建时也不会有积压(即没有消息等待传送)。
如需详细了解如何使用订阅,请参阅创建和使用订阅。
后续步骤
- 详细了解拉取订阅。
- 详细了解推送订阅。
- 详细了解 BigQuery 订阅。