发布失败通常是由客户端瓶颈导致的,例如服务 CPU 不足,线程运行状况不佳或网络拥塞。发布者重试政策定义了 Pub/Sub 尝试传送消息的次数以及每次尝试之间的时间长度。
本文档介绍了如何将重试请求与发布到主题的消息搭配使用。
准备工作
在配置发布工作流之前,请确保您已完成以下任务:
所需角色
如需获得重试向主题发送消息请求所需的权限,请让您的管理员向您授予主题的Pub/Sub 发布者 (roles/pubsub.publisher) IAM 角色。如需详细了解如何授予角色,请参阅管理对项目、文件夹和组织的访问权限。
您也可以通过自定义 角色或其他预定义 角色来获取所需的权限。
您需要额外的权限才能 创建或更新主题和订阅。
重试请求简介
重试设置控制 Pub/Sub 客户端库重试发布请求的方式。客户端库具有以下重试设置:
- 初始请求超时:客户端库 停止等待初始发布请求完成前的时间。
- 重试延迟:请求超时后,客户端库等待请求重试的时间。
- 总超时:客户端库停止重试发布请求后的时间量。
如需重试发布请求,初始请求超时必须短于总超时。例如,如果您使用的是指数退避算法,客户端库会按如下所示计算请求超时和重试延迟:
- 每个发布请求后,请求超时会以请求超时倍数增加,最长为请求超时上限。
- 每次重试后,重试延迟时间会以重试延迟倍数增加,最长为重试延迟上限。
重试消息请求
在发布过程中,您可能会看到暂时性或永久性发布失败。对于暂时性错误,您通常无需采取任何特殊操作,因为 Pub/Sub 会自动重试消息。
当发布操作成功,但发布者客户端未及时收到发布响应时,也可能会发生错误。在这种情况下,系统也会重试发布操作。因此,您可能会收到两条内容相同但消息 ID 不同的消息。
如果出现持续性错误,请考虑在发布过程之外实现适当的操作,以避免 Pub/Sub 负载过重。
如果发布失败,系统会自动重试,但无法保证能够重试的错误除外。此示例代码演示了如何使用自定义 重试设置创建发布者(请注意,并非所有客户端库都支持自定义重试 设置;请参阅适用于您所选语言的API 参考文档 ):
C++
在尝试此示例之前,请按照《快速入门:使用客户端库》中的 C++ 设置说明进行操作。如需了解详情,请参阅 Pub/Sub C++ API 参考文档。
C#
在尝试此示例之前,请按照《快速入门:使用客户端库》中的 C# 设置说明进行操作。 如需了解详情,请参阅 Pub/Sub C# API 参考文档。
Go
以下示例使用 Go Pub/Sub 客户端库的主要版本 (v2)。如果您仍在使用 v1 库,请参阅 v2 迁移指南。 如需查看 v1 代码示例列表,请参阅 已废弃的代码示例。
在尝试此示例之前,请按照 《快速入门:使用客户端库》中的 Go 设置说明进行操作。 如需了解详情,请参阅 Pub/Sub Go API 参考文档。
Java
在尝试此示例之前,请按照《快速入门:使用客户端库》中的 Java 设置说明进行操作。 如需了解详情,请参阅 Pub/Sub Java API 参考文档。
Node.js
在尝试此示例之前,请按照 《快速入门:使用客户端库》中的 Node.js 设置说明进行操作。 如需了解详情,请参阅Pub/Sub Node.js API 参考文档。
Node.js
在尝试此示例之前,请按照 《快速入门:使用客户端库》中的 Node.js 设置说明进行操作。 如需了解详情,请参阅Pub/Sub Node.js API 参考文档。
Python
在尝试此示例之前,请按照《快速入门:使用客户端库》中的 Python 设置说明进行操作。 如需了解详情,请参阅 Pub/Sub Python API 参考文档。
使用排序键重试请求
假设您有一个发布者客户端。您正在使用 Pub/Sub 客户端库为同一排序键 A 发布消息 1、2 和 3。现在,假设发布者客户端在 RPC 截止时间到期之前未收到消息 1 的发布响应。消息 1 必须重新发布。如果您假设消息 2 仅在消息 1 成功完成后发布,那么订阅者客户端收到的消息序列将变为 1、1、2 和 3。每条发布的消息都有自己的消息 ID。从订阅者客户端的角度来看,发布了四条消息,前两条消息的内容相同。
使用排序键重试发布请求也可能会因批处理设置而变得复杂。客户端库会将消息批量处理在一起,以便更高效地发布。继续使用前面的示例,并假设消息 1 和 2 批量处理在一起。此批处理将作为单个请求发送到服务器。如果服务器未能及时返回响应,发布者客户端会重试此批处理中的两条消息。因此,订阅者客户端可能会收到消息 1、2、1、2 和 3。如果您使用 Pub/Sub 客户端库按顺序发布消息,并且发布操作失败,则该服务会使同一排序键上的所有剩余消息的发布操作失败。然后,发布者客户端可以决定执行以下任一操作:
按顺序重新发布所有失败的消息
按顺序重新发布失败消息的子集
发布一组新消息
如果出现不可重试的错误,则客户端库无法发布消息,并会停止发布带有相同排序键的其他消息。例如,当发布者将消息发送到不存在的主题时,即会发生不可重试的错误。要继续发布带用相同排序键的消息,请调用一个方法以继续发布,然后开始重新发布。
以下示例显示了如何继续发布带有相同排序键的消息。
C++
在尝试此示例之前,请按照《快速入门:使用客户端库》中的 C++ 设置说明进行操作。如需了解详情,请参阅 Pub/Sub C++ API 参考文档。
C#
在尝试此示例之前,请按照《快速入门:使用客户端库》中的 C# 设置说明进行操作。 如需了解详情,请参阅 Pub/Sub C# API 参考文档。