本页面介绍了如何使用“正好一次”来接收和确认消息 语义信息。只有拉取订阅类型支持“正好一次”传送, 包括使用 StreamingPull API。
推送和导出订阅 不支持“正好一次”传送。
推荐的客户端库版本
- 为获得最佳性能,请使用最新版本的 Python 客户端库 v2.13.6 或更高版本, Java v1.120.11 或更高版本, 菲律宾比索 v1.39.0 或更高版本; C# v3.2.0 或更高版本, C++ v2.1.0、 前往 v1.25.1 或更高版本、 节点 v3.2.0 或更高版本 和 Ruby v2.12.1 或更高版本。
仅传送一次
Pub/Sub 支持在云区域内、 基于 Pub/Sub 定义的唯一 消息 ID。
启用此功能后,Pub/Sub 将提供以下内容:
成功确认消息后,不会重新传送。
当邮件未完成时,系统不会重新递送。将消息视为 未完成,直到确认时限结束或消息 已确认。
如果存在多次有效提交,由于存在确认截止期限 到期或客户端发起的否定确认,仅限最新的 确认 ID 可用于确认消息。包含 之前的确认 ID 失败。
重新提交与重复提交
了解预期结果与预期结果之间的区别很重要 重新提交。
由于客户发起的负面事件,可能会发生重新提交 确认消息,或者当客户端不扩展确认时 消息的截止时间。重新提交 被视为有效,且系统按预期运行。
要排查重新提交问题,请参阅处理重复内容。
重复项是指在成功确认后重新发送的消息 或确认截止期限之前。
重新递送的邮件两次尝试保留相同的邮件 ID。
启用了“仅传送一次”功能的订阅不会收到重复的消息 送货。
客户端库中的“正好一次”传送支持
支持的客户端库具有用于确认的接口 包含回复 (例如:Go)。 您可以使用此接口检查确认请求是否成功。 如果确认请求成功,则保证客户端 不会获得重新提交。如果确认请求失败, 客户可能会需要重新提交。
客户端也可以在不使用确认接口的情况下使用受支持的客户端库。不过,在这种情况下 确认失败会导致消息静默地重新提交。
支持的客户端库具有用于设置最低数量要求的接口 租期延期时间(例如: Go)。 您必须将最短租期延期的值设置为较大的数字 以避免任何与网络相关的确认过期。 最大值设置为 600 秒。
与精确一次传送相关的变量的默认值和范围,以及变量的名称可能会因客户端库而异。对于 例如,在 Java 客户端库中,以下变量控制 一次性交付。
变量 | 说明 | 值 |
---|---|---|
setEnableExactlyOnceDelivery |
启用或停用“正好一次”投放。 | true 或 false,默认值=false |
minDurationPerAckExtension |
用于延长修改确认时限的最短时间(以秒为单位)。 | 范围=0 到 600 默认值=无 |
maxDurationPerAckExtension |
用于延长修改确认时限的最长时间(以秒为单位)。 | 范围=0 到 600 默认值=无 |
对于仅传送一次,modifyAckDeadline
或 acknowledgment
向 Pub/Sub 发出的请求失败。在此类
在这种情况下,服务会将过期的确认 ID 视为无效,因为
较新的投放可能已经在进行中。这是出于正好一次的设计
。然后,您会看到 acknowledgment
和 ModifyAckDeadline
请求返回一个
INVALID_ARGUMENT
响应。停用“恰好一次”传送后,如果确认 ID 已过期,这些请求会返回 OK
。
为了确保 acknowledgment
和 ModifyAckDeadline
请求有效
请考虑将
minDurationPerAckExtension
到较大的数字。
地区注意事项
仅传送一次保证仅适用于订阅者在同一区域内连接到服务的情况。如果您的订阅者应用分布于 则可能会导致重复递送邮件,即使 启用“正好一次”投放发布者可以向任意区域 保证仅有一次。
当您在 Google Cloud 中运行自己的应用时, 连接到同一区域中的 Pub/Sub 端点。因此, 在 Google Cloud 内的单个区域中运行应用 通常可以确保您与单个区域进行互动。
在 Google Cloud 之外运行订阅者应用时 还是在多个区域,您可以保证连接到单个区域 通过在配置 Pub/Sub 时使用位置端点 客户端。Pub/Sub 的所有位置端点均指向单个 区域。如需详细了解位置端点, 请参阅 Pub/Sub 端点。 如需查看 Pub/Sub 的所有位置端点列表,请参阅位置端点列表。
创建“仅传送一次”的订阅
您可以使用 Google Cloud 控制台、Google Cloud CLI、客户端库或 Pub/Sub API 创建仅传送一次的订阅。
拉取订阅
控制台
如需创建具有正好一次传送的拉取订阅,请按照以下步骤操作:
在 Google Cloud 控制台中,进入订阅页面。
点击创建订阅。
输入订阅 ID。
从下拉菜单中选择或创建一个主题。
订阅将接收来自该主题的消息。
在仅传送一次部分,选择启用仅传送一次。
点击创建。
gcloud
如需创建具有正好一次传送的拉取订阅,请使用
gcloud pubsub subscriptions create
命令:--enable-exactly-once-delivery
gcloud pubsub subscriptions create SUBSCRIPTION_ID \ --topic=TOPIC_ID \ --enable-exactly-once-delivery
替换以下内容:
- SUBSCRIPTION_ID:要创建的订阅的 ID
- TOPIC_ID:要附加到订阅的主题的 ID
REST
如需创建“仅传送一次”的订阅,请使用
projects.subscriptions.create
方法。
PUT https://pubsub.googleapis.com/v1/projects/PROJECT_ID/subscriptions/SUBSCRIPTION_ID Authorization: Bearer $(gcloud auth print-access-token)
替换以下内容:
- PROJECT_ID:要在其中创建订阅的项目的 ID
- SUBSCRIPTION_ID:要创建的订阅的 ID
如需创建具有正好一次传送的拉取订阅,请指定以下代码 :
{ "topic": "projects/PROJECT_ID/topics/TOPIC_ID", "enableExactlyOnceDelivery": true, }
替换以下内容:
- PROJECT_ID:包含主题的项目的 ID
- TOPIC_ID:要附加到订阅的主题的 ID
C++
在尝试此示例之前,请按照《快速入门:使用客户端库》中的 C++ 设置说明进行操作。如需了解详情,请参阅 Pub/Sub C++ API 参考文档。
C#
在尝试此示例之前,请按照《快速入门:使用客户端库》中的 C# 设置说明进行操作。 如需了解详情,请参阅 Pub/Sub C# API 参考文档。
Go
在尝试此示例之前,请按照《快速入门:使用客户端库》中的 Go 设置说明进行操作。 如需了解详情,请参阅 Pub/Sub Go API 参考文档。
Java
在尝试此示例之前,请按照《快速入门:使用客户端库》中的 Java 设置说明进行操作。 如需了解详情,请参阅 Pub/Sub Java API 参考文档。
Python
在尝试此示例之前,请按照《快速入门:使用客户端库》中的 Python 设置说明进行操作。 如需了解详情,请参阅 Pub/Sub Python API 参考文档。
Node.js
在尝试此示例之前,请按照《快速入门:使用客户端库》中的 Node.js 设置说明进行操作。如需了解详情,请参阅 Pub/Sub Node.js API 参考文档。
Node.js
在尝试此示例之前,请按照《快速入门:使用客户端库》中的 Node.js 设置说明进行操作。如需了解详情,请参阅 Pub/Sub Node.js API 参考文档。
Ruby
在尝试此示例之前,请按照《快速入门:使用客户端库》中的 Ruby 设置说明进行操作。 如需了解详情,请参阅 Pub/Sub Ruby API 参考文档。
PHP
在尝试此示例之前,请按照《快速入门:使用客户端库》中的 PHP 设置说明进行操作。如需了解详情,请参阅 Pub/Sub PHP API 参考文档。
使用“仅传送一次”消息传送方式进行订阅
以下是使用客户端库订阅“正好一次”传送的一些代码示例。
拉取订阅
Go
在尝试此示例之前,请按照Go Pub/Sub 快速入门: 客户端库。 有关详情,请参阅 Pub/Sub Go API 参考文档。
如需向 Pub/Sub 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为本地开发环境设置身份验证。
Java
在尝试此示例之前,请按照Java Pub/Sub 快速入门: 客户端库。 有关详情,请参阅 Pub/Sub Java API 参考文档。
如需向 Pub/Sub 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为本地开发环境设置身份验证。
Node.js
在尝试此示例之前,请按照Node.js Pub/Sub 快速入门: 客户端库。 有关详情,请参阅 Pub/Sub Node.js API 参考文档。
如需向 Pub/Sub 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为本地开发环境设置身份验证。
PHP
在尝试此示例之前,请按照PHP Pub/Sub 快速入门: 客户端库。 有关详情,请参阅 Pub/Sub PHP API 参考文档。
如需向 Pub/Sub 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为本地开发环境设置身份验证。
Python
在尝试此示例之前,请按照Python Pub/Sub 快速入门: 客户端库。 有关详情,请参阅 Pub/Sub Python API 参考文档。
如需向 Pub/Sub 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为本地开发环境设置身份验证。
Ruby
在尝试此示例之前,请按照Ruby Pub/Sub 快速入门: 客户端库。 有关详情,请参阅 Pub/Sub Ruby API 参考文档。
如需向 Pub/Sub 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为本地开发环境设置身份验证。
C++
在尝试此示例之前,请按照C++ Pub/Sub 快速入门: 客户端库。 有关详情,请参阅 Pub/Sub C++ API 参考文档。
如需向 Pub/Sub 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为本地开发环境设置身份验证。
C#
在尝试此示例之前,请按照C# Pub/Sub 快速入门: 客户端库。 有关详情,请参阅 Pub/Sub C# API 参考文档。
如需向 Pub/Sub 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为本地开发环境设置身份验证。
Node.js (TypeScript)
在尝试此示例之前,请按照 Pub/Sub 快速入门: 客户端库。 有关详情,请参阅 Pub/Sub Node.js API 参考文档。
如需向 Pub/Sub 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为本地开发环境设置身份验证。
监控“仅传送一次”传送订阅
通过
subscription/exactly_once_warning_count
指标会记录
可能会导致重新提交(有效或重复)。该指标统计的是
Pub/Sub 无法处理与
确认 ID(ModifyAckDeadline
或 acknowledgment
请求)。原因
可能基于服务器或客户端例如,如果持久性
用于保持“正好一次”交付信息的层不可用,
事件。如果客户端尝试使用
确认 ID 无效,则是基于客户端的事件。
了解指标
subscription/exactly_once_warning_count
会捕获可能会或不可能发生的事件
会导致实际重新提交,并且可能会因为客户行为而产生干扰。对于
示例:针对无效的重复 acknowledgment
或 ModifyAckDeadline
请求
确认 ID 会反复递增指标。
以下指标也有助于了解客户端行为:
subscription/expired_ack_deadlines_count
指标显示确认 ID 过期次数。确认 ID 过期可能会导致ModifyAckDeadline
和acknowledgment
请求。service.serviceruntime.googleapis.com/api/request_count
指标可用于捕获ModifyAckDeadline
或acknowledgment
的失败情况 在请求到达 Google Cloud 但未到达 连接到 Pub/Sub。有失败,则此指标不会 捕获数据,例如在客户端与 Google Cloud 断开连接时。
在大多数情况下可以重试的失败事件中,使用支持的客户端库 并自动重试请求。
配额
“正好一次”传送订阅受额外配额的约束 要求。这些配额适用于:
- 通过“正好一次传送”的订阅所使用的消息数 每个区域启用
- 在启用“仅传送一次”功能的订阅中,每个区域收到确认或延长截止期限的消息数量。
有关这些配额的详细信息,请参阅 配额主题。
“正好一次”递送和订购的订阅
Pub/Sub 支持使用有序传送仅传送一次。
使用“正好一次”传送的排序时,Pub/Sub 期望 让确认保持顺序如果确认顺序有误,则 服务会让请求失败并出现临时错误。如果确认时限 在提交确认之前到期,客户端将 收到重新递送的邮件。因此,当您使用 正好一次传送,则客户端吞吐量上限为 1000 个 每秒显示 1 条消息。
“正好一次”传送和推送订阅
Pub/Sub 仅支持使用拉取订阅进行“正好一次”传送。
使用来自推送订阅的消息的客户端会确认消息 以成功响应来响应推送请求。不过,客户端 不知道 Pub/Sub 订阅是否收到了响应 已处理。这与拉取订阅不同,在拉取订阅中,确认请求由客户端发起,并且在 Pub/Sub 订阅成功处理请求时做出响应。因此 “正好一次”传送语义与推送订阅不太一致。
注意事项
如果 CreateSubscription 时间未指定确认截止时间, 已启用“正好一次传送”的订阅将具有默认确认 设为 60 秒
设置较长的默认确认时限有助于避免 由网络事件导致的重新提交受支持的客户端库不使用 默认的订阅确认截止期限。
“仅传送一次”订阅方案的比例要高得多 与常规订阅相比,发布到订阅的延迟时间。
即使启用了“正好一次”传送,订阅可能会因发布端重复而收到相同消息的多个副本。发布端重复可能是由 发布客户端或 Pub/Sub 服务如果发布客户端多次进行不重复的发布,且多次重试,则会导致以不同的消息 ID 重新提交。为了响应客户端发布请求,Pub/Sub 服务进行了多次唯一发布操作会导致以相同的消息 ID 重新提交。
您可以在
subscription/exactly_once_warning_count
中重试失败的测试,支持的客户端库会重试这些测试 。但是,与无效确认 ID 相关的失败情况无法 重试。