订阅属性

Pub/Sub 订阅属性是指订阅的特征。 您可以在创建或更新订阅时设置订阅属性。

本文档介绍了您可以为订阅设置的不同订阅属性。

准备工作

常见订阅属性

创建订阅时,您必须指定多个选项才能设置订阅。其中一些属性是所有类型的订阅共有的,将在下文中进行讨论。

消息保留时长

消息保留时长选项用于指定 Pub/Sub 在发布后保留消息的时间。超过消息保留时长之后,Pub/Sub 可以随意舍弃消息,无论其确认状态为何。如需保留已确认的消息,请参阅重放和舍弃消息

“消息保留时长”选项的值如下:

  • 默认值 = 7 天
  • 最小值 = 10 分钟
  • 最大值 = 31 天

未确认的消息可能是由闲置订阅、备份需求或处理速度缓慢造成的。如果您能在 24 小时内处理这些消息,则不会产生额外费用。您可以按以下方式管理这些情况,以免产生新的费用:

  • 闲置订阅删除空闲的订阅,以免产生订阅消息保留费用。

  • 备份存储。如果您使用订阅保留作为备份存储空间,可以改用其他存储选项,例如主题消息保留或保留已确认的消息。主题消息保留功能仅在主题级存储消息一次,并且在需要时,所有订阅都可以使用这些消息。

  • 处理延迟。添加更多订阅者(如果可能),以便在一天内处理消息。

保留已确认的消息

如果您指定了消息保留时长,还可以指定是否要保留已确认的消息。

借助保留已确认的消息选项,您可以将已确认的消息保留指定的消息保留时长。 此选项会增加消息存储费用。如需了解详情,请参阅存储费用

有效期

借助到期期限选项,您可以延长订阅的到期期限。

如果没有订阅者活动或订阅属性发生任何更改,则订阅会过期。如果 Pub/Sub 检测到订阅者活动,或者您更新了任何订阅属性,则订阅删除时钟会重新启动。订阅者活动包括打开连接、主动拉取或成功推送等。

如果您指定了过期期限,该值必须至少与消息保留期限选项中指定的消息保留时长一样长。

以下是过期期限选项的值:

  • 默认值 = 31 天
  • 最小值 = 1 天

要阻止订阅过期,请将有效期设置为 never expire

确认截止期限

确认截止期限选项用于指定初始截止期限,超过此期限后,系统会重新发送未确认的消息。您可以通过发送后续 ModifyAckDeadline 请求,按消息延长确认期限。

以下是确认截止时间选项的值:

  • 默认值 = 10 秒
  • 最小值 = 10 秒
  • 最大值 = 600 秒

在某些情况下,Pub/Sub 客户端库可以控制传送速率并动态修改确认期限。这样做可能会导致消息在您设置的确认截止期限之前重新传送。如需替换此行为,请使用 minDurationPerAckExtensionmaxDurationPerAckExtension。如需详细了解如何使用这些值,请参阅客户端库中的“只发送一次”交付支持

单条消息转换 (SMT)

借助 SMT,可以直接在 Pub/Sub 中对消息属性和数据进行轻量级修改。此功能可在消息传递到订阅者客户端之前进行数据清理、过滤或格式转换。

如需了解详情,请参阅 SMT 概览创建包含 SMT 的订阅

订阅过滤条件

使用订阅过滤条件选项指定包含过滤表达式的字符串。如果某个订阅具有过滤条件,则该订阅将仅传递与过滤条件匹配的消息。Pub/Sub 服务会自动确认与过滤条件不匹配的消息。

  • 您可以按消息的属性过滤消息,但不能按消息中的数据过滤消息。

  • 如果未指定,则订阅不会过滤消息,并且订阅者会收到所有消息。

  • 过滤条件一经应用便无法更改或移除。

当您收到包含过滤条件的订阅的消息时,您无需为 Pub/Sub 自动确认的消息支付出站流量费用。您需要支付消息传送费用以及跳转相关存储费用。

如需了解详情,请参阅过滤订阅中的消息

消息排序

如果订阅已启用消息排序,则订阅者客户端会按服务接收消息的顺序接收在同一区域中发布且具有相同排序键的消息。

使用按序传送时,系统不会处理后续消息的确认,直到处理完之前消息的确认。

发布者必须使用排序键发送消息,以便 Pub/Sub 可以按顺序传送消息

如果未设置消息排序,则 Pub/Sub 可能不会按顺序传送消息,即使消息具有排序键也是如此。

死信主题

如果消息在经过一定次数的传送尝试后仍无法传送,或者订阅者无法确认消息,您可以配置一个死信主题,以便将这些消息重新发布到该主题。

如果设置了死信主题,还可以指定传送尝试次数上限。以下是死信主题的传送尝试次数上限值:

  • 默认值 = 5 次传送尝试
  • 最小值 = 5 次传送尝试
  • 最大值 = 100 次传送尝试

如果死信主题与订阅位于不同的项目中,那么您还必须指定具有死信主题的项目 ID。

如需了解详情,请参阅转发到死信主题

重试政策

如果确认截止时间到期或订阅者返回否定确认,则 Pub/Sub 可以再次发送消息。此重新传送尝试称为订阅重试政策

默认情况下,订阅的重试政策设置为使用立即重试。如果选择此选项,Pub/Sub 会在确认截止时间到期或订阅者做出否定确认响应时重新发送消息。

您还可以将该值设置为在按照指数退避算法确定的延迟时间后重试。在这种情况下,您必须指定最大退避值和最小退避值。

以下是设置最大和最小退避值的准则:

  • 如果您设置了退避时长的最大值,则最小退避时长的默认值为 10 秒。

  • 如果您设置了退避时长的最小值,则最大退避时长的默认值为 600 秒。

  • 可指定的最长退避时长为 600 秒。

重试政策和批处理消息

如果消息采用批处理,则在发生以下任一情况时,Pub/Sub 会启动指数退避算法:

  • 订阅者为批次中的每条消息发送否定确认。

  • 确认截止时间到期。

重试政策和推送订阅

如果收到推送订阅消息,Pub/Sub 可能会在推送退避时限(而非指数退避时限)后传送消息。当推送退避时间超过指数退避时限时,Pub/Sub 会在推送退避后重新提交未确认的消息。

拉取订阅属性

配置拉取订阅时,您可以指定以下属性。

仅传送一次

仅传送一次。如果设置,Pub/Sub 会履行正好一次传送保证。如果未指定,则订阅支持每条消息的“至少一次”传送。

推送订阅属性

配置推送订阅时,您可以指定以下属性。

端点

端点网址(必需)。可公开访问的 HTTPS 地址。推送端点的服务器必须具有由证书授权机构签署的有效 SSL 证书。Pub/Sub 服务会将同一 Trusted Cloud 区域中的消息传送至 Pub/Sub 服务存储消息所在的推送端点。Pub/Sub 服务会尽最大努力传送来自同一 Trusted Cloud 区域的消息。

  • 如果订阅者使用防火墙,则无法接收推送请求。如需接收推送请求,您必须关闭防火墙并验证请求中使用的 JSON Web 令牌 (JWT)。如果订阅者有防火墙,您可能会收到 403 permission denied 错误。

  • Pub/Sub 不再要求证明对推送订阅网址网域的所有权。如果您的网域收到来自 Pub/Sub 的意外 POST 请求,您可以举报疑似滥用行为

身份验证

启用身份验证。启用后,Pub/Sub 传送到推送端点的消息会包含授权标头,以允许端点对请求进行身份验证。如果 App Engine 标准应用和 Cloud Run functions 端点托管在订阅所属的项目中,则可以使用自动身份验证和授权机制。

经过身份验证的推送订阅的身份验证配置包含用户代管式服务账号,以及在 createpatchModifyPushConfig 调用中指定的受众群体参数。您还必须向服务账号授予特定角色,如下一部分中所述。

  • 受众群体。一个不区分大小写的字符串,供 Webhook 用于验证此特定令牌的目标受众群体。

  • 服务账号。Pub/Sub 会自动为您创建一个格式为 service-{PROJECT_NUMBER}@gcp-sa-pubsub.s3ns-system.iam.gserviceaccount.com 的服务账号。

启用身份验证的先决条件

用户管理的服务账号是与推送订阅关联的服务账号。此账号用作生成的 JSON Web 令牌 (JWT) 的 email 声明。以下是服务账号的要求列表:

  • 用户代管式服务必须与推送订阅位于同一项目中。

  • 创建或修改推送订阅的主账号必须拥有用户管理的服务账号iam.serviceAccounts.actAs 权限,才能将该服务账号附加到推送订阅。如需了解详情,请参阅将服务账号附加到资源

  • 所需权限:必须向此服务账号授予 iam.serviceAccounts.getOpenIdToken 权限(包含在 roles/iam.serviceAccountTokenCreator 角色中),以允许 Pub/Sub 为指定的服务账号创建 JWT 令牌,从而对推送请求进行身份验证。

载荷解封

启用载荷解封选项会从 Pub/Sub 消息中剥离所有消息元数据,但消息数据除外。通过载荷解封装,消息数据会直接作为 HTTP 正文传递。

您还可以启用写入元数据选项。写入元数据选项会将之前移除的消息元数据重新添加到请求标头中。

BigQuery 属性

如果选择 Write to BigQuery 作为订阅传送类型,您可以指定以下其他属性。

使用主题架构

此选项可让 Pub/Sub 使用订阅所附加的 Pub/Sub 主题的架构。此外,Pub/Sub 还会将消息中的字段写入 BigQuery 表中的相应列。

使用此选项时,请务必检查是否满足以下额外要求:

  • 主题架构和 BigQuery 架构中的字段必须具有相同的名称,并且它们的类型必须相互兼容。

  • 主题架构中的任何可选字段在 BigQuery 架构中也必须是可选字段。

  • 主题架构中的必需字段在 BigQuery 架构中不必是必需字段。

  • 如果主题架构中没有 BigQuery 字段,则这些 BigQuery 字段必须处于 NULLABLE 模式。

  • 如果主题架构包含 BigQuery 架构中没有的其他字段,并且可以舍弃这些字段,请选择舍弃未知字段选项。

  • 您只能选择一个订阅属性,即使用主题架构使用表架构

如果您未选择使用主题架构使用表架构选项,请确保 BigQuery 表有一个名为 data 的列,其类型为 BYTESSTRINGJSON。Pub/Sub 会将消息写入此 BigQuery 列。

您可能不会立即看到写入 BigQuery 表的消息中 Pub/Sub 主题架构或 BigQuery 表架构的更改生效。例如,如果启用了舍弃未知字段选项,并且某个字段存在于 Pub/Sub 架构中,但不存在于 BigQuery 架构中,那么即使将该字段添加到 BigQuery 架构中,写入 BigQuery 表的消息可能仍然不包含该字段。最终,架构会同步,后续消息会包含该字段。

为 BigQuery 订阅使用使用主题架构选项时,您还可以利用 BigQuery 变更数据捕获 (CDC) 功能。CDC 通过处理更改并将更改应用于现有行来更新 BigQuery 表。

如需详细了解此功能,请参阅使用变更数据捕获来流式插入表更新

如需了解如何将此功能与 BigQuery 订阅搭配使用,请参阅 BigQuery 变更数据捕获

使用表架构

此选项可让 Pub/Sub 使用 BigQuery 表的架构将 JSON 消息的字段写入相应的列。使用此选项时,请务必检查以下附加要求:

  • BigQuery 表中每个列的名称只能包含字母(a-z、A-Z)、数字 (0-9) 或下划线 (_)。

  • 发布的消息必须采用 JSON 格式。

  • 支持以下 JSON 转换:

    JSON 类型 BigQuery 数据类型
    string NUMERICBIGNUMERICDATETIMEDATETIMETIMESTAMP
    number NUMERICBIGNUMERICDATETIMEDATETIMETIMESTAMP
    • 使用 number 将转化设置为 DATEDATETIMETIMETIMESTAMP 时,该数字必须符合支持的表示形式
    • 使用 numberNUMERICBIGNUMERIC 的转换时,值的精度和范围仅限于 IEEE 754 浮点运算标准所接受的精度和范围。如果您需要高精度或更广的值范围,请改用 stringNUMERICBIGNUMERIC 转换。
    • 使用 stringNUMERICBIGNUMERIC 的转换时,Pub/Sub 会假定该字符串是人类可读的数字(例如 "123.124")。如果将该字符串处理为人类可读的数字失败,Pub/Sub 会将该字符串视为使用 BigDecimalByteStringEncoder 编码的字节。
  • 如果订阅的主题具有关联的架构,则消息编码属性必须设置为 JSON

  • 如果存在消息中没有的 BigQuery 字段,则这些 BigQuery 字段必须处于 NULLABLE 模式。

  • 如果消息包含 BigQuery 架构中没有的其他字段,并且可以舍弃这些字段,请选择舍弃未知字段选项。

  • 您只能选择一个订阅属性,即使用主题架构使用表架构

如果您未选择使用主题架构使用表架构选项,请确保 BigQuery 表有一个名为 data 的列,其类型为 BYTESSTRINGJSON。Pub/Sub 会将消息写入此 BigQuery 列。

您可能不会立即看到写入 BigQuery 表的消息对 BigQuery 表架构产生影响。例如,如果启用了舍弃未知字段选项,并且消息中存在某个字段,但 BigQuery 架构中不存在该字段,那么即使将该字段添加到 BigQuery 架构中,写入 BigQuery 表的消息可能仍然不包含该字段。最终,架构会同步,后续消息会包含该字段。

为 BigQuery 订阅使用使用表架构选项时,您还可以利用 BigQuery 变更数据捕获 (CDC)。CDC 通过处理更改并将更改应用于现有行来更新 BigQuery 表。

如需详细了解此功能,请参阅使用变更数据捕获来流式插入表更新

如需了解如何将此功能与 BigQuery 订阅搭配使用,请参阅 BigQuery 变更数据捕获

删除未知字段

此选项与使用主题架构使用表架构选项搭配使用。启用此选项后,Pub/Sub 可以舍弃主题架构或消息中存在但 BigQuery 架构中不存在的任何字段。将消息写入 BigQuery 表时,不属于 BigQuery 架构的字段会被舍弃。

如果不设置舍弃未知字段,则包含额外字段的消息不会写入 BigQuery,并且会保留在订阅积压消息中,除非您配置死信主题

舍弃未知字段设置不会影响 Pub/Sub 主题架构或 BigQuery 表架构中未定义的字段。在这种情况下,有效的 Pub/Sub 消息会传递给订阅。不过,由于 BigQuery 没有为这些额外字段定义列,因此在 BigQuery 写入过程中,这些字段会被舍弃。为防止出现此行为,请确保 Pub/Sub 消息中包含的所有字段也包含在 BigQuery 表架构中。

有关额外字段的行为也可能取决于所用的特定架构类型(Avro、Protocol Buffer)和编码(JSON、二进制)。如需了解这些因素如何影响额外字段的处理,请参阅特定架构类型和编码的文档。

写入元数据

此选项可让 Pub/Sub 将每条消息的元数据写入 BigQuery 表中的其他列。否则,元数据不会写入 BigQuery 表。

如果您选择写入元数据选项,请确保 BigQuery 表具有下表中所述的字段。

如果您未选择写入元数据选项,则目标 BigQuery 表仅需要 data 字段,除非 use_topic_schema 为 true。如果您同时选择写入元数据使用主题架构选项,则主题的架构不得包含任何名称与元数据参数名称相同的字段。此限制包括这些 snake case 参数的 camelcase 版本。

参数
subscription_name

STRING

订阅的名称。

message_id

STRING

消息的 ID

publish_time

TIMESTAMP

发布消息的时间。

data

BYTES、STRING 或 JSON

消息正文。

对于未选择使用主题架构使用表架构的所有目标 BigQuery 表,data 字段都是必需的。如果该字段的类型为 JSON,则消息正文必须是有效的 JSON。

attributes

STRING 或 JSON

包含所有消息属性的 JSON 对象。它还包含 Pub/Sub 消息的其他字段,包括排序键(如果存在)。

Cloud Storage 属性

如果您选择的订阅传送类型为写入 Cloud Storage,则可以指定以下其他属性。

存储桶名称

在创建 Cloud Storage 订阅之前,必须先创建 Cloud Storage 存储桶。

这些消息会以批次形式发送,并存储在 Cloud Storage 存储桶中。单个批次或文件以对象的形式存储在存储桶中。

Cloud Storage 存储桶必须停用请求者付款

如需创建 Cloud Storage 存储桶,请参阅创建存储分区

文件名前缀、后缀和日期时间

由 Cloud Storage 订阅生成的输出 Cloud Storage 文件以对象的形式存储在 Cloud Storage 存储桶中。存储在 Cloud Storage 存储桶中的对象的名称采用以下格式:<file-prefix><UTC-date-time>_<uuid><file-suffix>

以下列表详细介绍了文件格式以及您可以自定义的字段:

  • <file-prefix> 是自定义文件名前缀。这是一个可选字段。

  • <UTC-date-time> 是根据对象创建时间自动生成的自定义字符串。

  • <uuid> 是为对象自动生成的随机字符串。

  • <file-suffix> 是自定义文件名后缀。这是一个可选字段。文件名后缀不能以“/”结尾。

  • 您可以更改文件名前缀和后缀:

    • 例如,如果文件名前缀的值为 prod_,文件后缀的值为 _archive,则对象名称示例为 prod_2023-09-25T04:10:00+00:00_uN1QuE_archive

    • 如果您未指定文件名前缀和后缀,则存储在 Cloud Storage 存储桶中的对象名称的格式为:<UTC-date-time>_<uuid>

    • Cloud Storage 对象命名要求也适用于文件名前缀和后缀。如需了解详情,请参阅关于 Cloud Storage 对象

  • 您可以更改文件名中日期和时间的显示方式:

    • 必需的日期时间匹配器,只能使用一次:年(YYYYYY)、月(MM)、日(DD)、时(hh)、分(mm)、秒(ss)。例如,YY-YYYYMMM 无效。

    • 只能使用一次的可选匹配器:日期时间分隔符 (T) 和时区偏移量(Z+00:00)。

    • 可多次使用的可选元素:连字符 (-)、下划线 (_)、英文冒号 (:) 和正斜杠 (/)。

    • 例如,如果文件名日期时间格式的值为 YYYY-MM-DD/hh_mm_ssZ,则示例对象名称为 prod_2023-09-25/04_10_00Z_uNiQuE_archive

    • 如果文件名日期时间格式以非匹配字符结尾,该字符将替换 <UTC-date-time><uuid> 之间的分隔符。例如,如果文件名日期时间格式的值为 YYYY-MM-DDThh_mm_ss-,则示例对象名称为 prod_2023-09-25T04_10_00-uNiQuE_archive

文件批量处理

借助 Cloud Storage 订阅,您可以决定何时创建新输出文件并将其作为对象存储在 Cloud Storage 存储桶中。当满足指定的批处理条件之一时,Pub/Sub 会写入输出文件。以下是 Cloud Storage 批处理条件:

  • 批量存储时长上限。此设置是必需的。如果超过指定的最大时长值,Cloud Storage 订阅会写入新的输出文件。如果您未指定值,系统会应用 5 分钟的默认值。 以下是适用于最长时长的值:

    • 最小值 = 1 分钟
    • 默认值 = 5 分钟
    • 最大值 = 10 分钟
  • 批量存储字节数上限。这是一项可选设置。如果超过指定的最大字节数,Cloud Storage 订阅会写入新的输出文件。以下是最大字节数的适用值:

    • 最小值 = 1 KB
    • 最大值 = 10 GiB
  • 批量存储消息数上限。这是一项可选设置。如果超过指定的最大消息数,Cloud Storage 订阅会写入新的输出文件。以下是“最多消息数”的适用值:

    • 最小值 = 1000

例如,您可以将最长时长配置为 6 分钟,并将最大字节数配置为 2 GB。如果在第 4 分钟时,输出文件的大小达到 2 GB,Pub/Sub 会完成上一个文件的写入,并开始写入新文件。

Cloud Storage 订阅可能会同时写入 Cloud Storage 存储桶中的多个文件。如果您已将订阅配置为每 6 分钟创建一个新文件,您可能会发现每 6 分钟会创建多个 Cloud Storage 文件。

在某些情况下,Pub/Sub 可能会比文件批处理条件配置的时间更早开始写入新文件。如果订阅接收的消息大于最大字节数值,文件也可能会超出最大字节数值。

文件格式

创建 Cloud Storage 订阅时,您可以将要存储在 Cloud Storage 存储桶中的输出文件格式指定为文本Avro

  • 文本:消息以纯文本形式存储。换行符用于分隔消息与文件中的上一条消息。系统只会存储消息载荷,而不会存储属性或其他元数据。

  • Avro:消息以 Apache Avro 二进制格式存储。选择 Avro 时,您可以启用以下其他属性:

    • 写入元数据:此选项可让您将消息元数据与消息一起存储。subscription_namemessage_idpublish_timeattributes 字段等元数据会写入输出 Avro 对象中的顶级字段,而除数据之外的所有其他消息属性(例如 ordering_key,如果存在)都会作为条目添加到 attributes 映射中。

      如果停用了写入元数据,则只会将消息载荷写入输出 Avro 对象。以下是禁用了写入元数据的输出消息的 Avro 架构:

      {
        "type": "record",
        "namespace": "com.google.pubsub",
        "name": "PubsubMessage",
        "fields": [
          { "name": "data", "type": "bytes" }
        ]
      }
      

      以下是启用了写入元数据的输出消息的 Avro 架构:

      {
        "type": "record",
        "namespace": "com.google.pubsub",
        "name": "PubsubMessageWithMetadata",
        "fields": [
          { "name": "subscription_name", "type": "string" },
          { "name": "message_id", "type": "string"  },
          { "name": "publish_time", "type": {
              "type": "long",
              "logicalType": "timestamp-micros"
            }
          },
          { "name": "attributes", "type": { "type": "map", "values": "string" } },
          { "name": "data", "type": "bytes" }
        ]
      }
      
    • 使用主题架构:此选项可让 Pub/Sub 在写入 Avro 文件时使用订阅所附加的 Pub/Sub 主题的架构

      使用此选项时,请务必检查是否满足以下额外要求:

      • 主题架构必须采用 Apache Avro 格式

      • 如果同时启用了使用主题架构写入元数据,则主题架构的根必须是 Record 对象。Pub/Sub 将扩展记录的字段列表,以包含元数据字段。因此,记录不能包含任何与元数据字段(subscription_namemessage_idpublish_timeattributes)同名的字段。

服务账号

您可以通过以下方式将消息写入 BigQuery 表或 Cloud Storage 存储桶:

  • 配置自定义服务账号,以便只有拥有该服务账号的 iam.serviceAccounts.actAs 权限的用户才能创建可写入表或存储桶的订阅。包含 iam.serviceAccounts.actAs 权限的角色示例是 Service Account User (roles/iam.serviceAccountUser) 角色。

  • 使用默认的 Pub/Sub 服务代理,让任何能够在项目中创建订阅的用户都能创建写入表或存储桶的订阅。如果您未指定自定义服务账号,Pub/Sub 服务代理将是默认设置。

后续步骤