订阅者可能会因各种原因而无法处理消息。例如,检索处理消息所需的数据时可能会出现暂时性问题。或者,消息采用订阅者意料之外的格式。
本页面介绍了如何通过使用订阅重试政策或将未传送的消息转发到死信主题(也称为“死信队列”)来处理此类处理失败。
请注意,Dataflow 不支持这些功能。如需了解详情,请参阅 Dataflow 文档的不支持的 Pub/Sub 功能部分。
订阅重试政策
如果 Pub/Sub 尝试传送消息但订阅者无法确认该消息,则 Pub/Sub 会自动尝试重新发送消息。这种重新提交尝试称为订阅重试政策。您无法开启或关闭此功能。不过,您可以选择要使用的重试政策类型。
首次创建和配置订阅时,您可以选择使用以下重试政策之一:立即重新提交或指数退避算法。默认情况下,订阅会立即重新提交。
立即重新提交
默认情况下,Pub/Sub 会尝试立即重新发送该消息(并且可能会发送到同一订阅者客户端)。但是,如果阻止消息确认的条件未发生变化,立即重新提交可能会导致问题。在这种情况下,Pub/Sub 可能会重新发送多条无法确认的消息。
为了解决立即重新提交的问题,Pub/Sub 允许您配置指数退避算法政策。
指数退避算法
指数退避算法可让您在重试尝试之间逐渐增加延迟。第一次传送失败后,Pub/Sub 会等待最短退避时间后再重试。对于每次连续发送消息失败,延迟上会增加更多时间,最长延迟(0 和 600 秒)。
最大和最小延迟间隔不固定,应根据应用的本地因素进行配置。
请注意以下有关指数退避算法的注意事项:
- 执行以下操作会触发指数退避算法:
- 收到否定确认时。
- 消息的确认截止期限到期。
- 指数退避算法仅适用于每条消息,而不是应用于订阅(全局)中的所有消息。
- 使用指数退避算法时,即使之前的消息收到了否定确认,Pub/Sub 也会继续传送其他消息(除非您使用有序消息传送)。
配置指数退避算法
控制台
创建新订阅时,您可以执行以下步骤来配置指数退避算法重试政策:
gcloud
如需使用指数退避算法重试政策创建新订阅,请使用下面显示的标志运行 gcloud pubsub create
命令:
gcloud pubsub subscriptions create SUBSCRIPTION_ID \ --topic=TOPIC_ID \ --min-retry-delay=MIN_RETRY_DELAY \ --max-retry-delay=MAX_RETRY_DELAY
死信主题
如果 Pub/Sub 服务尝试传送消息但订阅者无法确认该消息,Pub/Sub 可以将无法传送的消息转发到死信主题。
死信主题如何与 Pub/Sub 搭配使用
死信主题是订阅属性,而不是主题属性。这意味着您在创建订阅时设置死信主题,而不是在创建主题时设置。
如果您创建死信主题,则可以设置以下订阅属性:
传送尝试次数上限:一个数值,表示 Pub/Sub 尝试传送特定消息的次数。如果订阅方客户端无法在配置的传送尝试次数内确认消息,则该消息将被转发到死信主题。
- 默认值 = 5
- 最大值 = 100
- 最小值 = 5
包含死信主题的项目:如果死信主题与订阅属于不同的项目,您必须指定包含死信主题的项目。将死信主题设置为与订阅所关联的主题不同的主题。
如何计算发送尝试次数上限
只有在正确配置死信主题并且包含正确的 IAM 权限时,Pub/Sub 才会统计传送尝试次数。
传送尝试次数上限是近似值,因为 Pub/Sub 会尽最大努力转发无法传送的消息。
跟踪的消息传送尝试次数也可能会重置为零,特别是对于具有非活跃订阅者的拉取订阅。因此,消息传送到订阅者客户端的次数可能会超过配置的传送尝试次数上限。
配置死信主题
如需配置死信主题,源主题必须先拥有订阅。您可以在创建订阅时指定死信主题,也可以更新现有订阅以使其包含死信主题。
以下是在订阅上启用死信的工作流程。
创建死信主题。该主题与源主题无关。
在源主题的订阅上设置死信主题。
为避免丢失死信主题的消息,请至少将另一个订阅附加到死信主题。辅助订阅会接收来自死信主题的消息。
将 Publisher 和 Subscriber 角色授予 Pub/Sub 服务帐号。如需了解详情,请参阅授予转发权限。
为新订阅设置死信主题
您可以使用 Google Cloud 控制台、Google Cloud CLI、客户端库或 Pub/Sub API 创建订阅并设置死信主题。
控制台
如需创建订阅并设置死信主题,请完成以下步骤:
在 Google Cloud 控制台中,进入订阅页面。
点击创建订阅。
输入订阅 ID。
从下拉菜单中选择或创建一个主题。
订阅将接收来自该主题的消息。
在死信部分,选择启用死信。
从下拉菜单中选择或创建死信主题。
如果选定的死信主题没有订阅,则系统会提示您创建一个订阅。
在传送尝试次数上限字段中,指定 5 到 100 之间的整数。
点击创建。
详细信息面板会显示可用操作项的列表。如果其中任何项显示错误图标
,请点击相应操作项以解决问题。
gcloud
如需创建订阅并设置死信主题,请使用 gcloud pubsub subscriptions create
命令:
gcloud pubsub subscriptions create subscription-id \ --topic=topic-id \ --dead-letter-topic=dead-letter-topic-name \ [--max-delivery-attempts=max-delivery-attempts] \ [--dead-letter-topic-project=dead-letter-topic-project]
C++
在尝试此示例之前,请按照《快速入门:使用客户端库》中的 C++ 设置说明进行操作。如需了解详情,请参阅 Pub/Sub C++ API 参考文档。
C#
在尝试此示例之前,请按照《快速入门:使用客户端库》中的 C# 设置说明进行操作。 如需了解详情,请参阅 Pub/Sub C# API 参考文档。
Go
在尝试此示例之前,请按照《快速入门:使用客户端库》中的 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 参考文档。
PHP
在尝试此示例之前,请按照《快速入门:使用客户端库》中的 PHP 设置说明进行操作。如需了解详情,请参阅 Pub/Sub PHP API 参考文档。
Python
在尝试此示例之前,请按照《快速入门:使用客户端库》中的 Python 设置说明进行操作。 如需了解详情,请参阅 Pub/Sub Python API 参考文档。
Ruby
在尝试此示例之前,请按照《快速入门:使用客户端库》中的 Ruby 设置说明进行操作。 如需了解详情,请参阅 Pub/Sub Ruby API 参考文档。
Ruby
在试用此示例之前,请按照“Pub/Sub 快速入门:使用客户端库”中的 Ruby 设置说明进行操作。如需了解详情,请参阅 Pub/Sub Ruby API 参考文档。
如需向 Pub/Sub 进行身份验证,请设置应用默认凭据。如需了解详情,请参阅为本地开发环境设置身份验证。
为现有订阅设置死信主题
您可以使用 Google Cloud 控制台、Google Cloud CLI、客户端库或 Pub/Sub API 更新订阅并设置死信主题。
控制台
如需更新订阅并设置死信主题,请完成以下步骤。
在 Google Cloud 控制台中,进入订阅页面。
在要更新的订阅旁边,点击更多操作more_vert。
在上下文菜单中,选择编辑。
在死信部分,选择启用死信。
从下拉菜单中选择或创建一个主题。
如果所选主题没有订阅,系统会提示您创建一个订阅。
在传送尝试次数上限字段中,指定 5 到 100 之间的整数。
点击更新。
详细信息面板会显示可用操作项的列表。如果其中任何项显示错误图标
,请点击相应操作项以解决问题。
gcloud
如需更新订阅并设置死信主题,请使用 gcloud pubsub subscriptions update
命令:
gcloud pubsub subscriptions update subscription-id \ --dead-letter-topic=dead-letter-topic-name \ [--max-delivery-attempts=max-delivery-attempts] \ [--dead-letter-topic-project=dead-letter-topic-project]
C++
在尝试此示例之前,请按照《快速入门:使用客户端库》中的 C++ 设置说明进行操作。如需了解详情,请参阅 Pub/Sub C++ API 参考文档。
C#
在尝试此示例之前,请按照《快速入门:使用客户端库》中的 C# 设置说明进行操作。 如需了解详情,请参阅 Pub/Sub C# API 参考文档。
Go
在尝试此示例之前,请按照《快速入门:使用客户端库》中的 Go 设置说明进行操作。 如需了解详情,请参阅 Pub/Sub Go API 参考文档。
Java
在尝试此示例之前,请按照《快速入门:使用客户端库》中的 Java 设置说明进行操作。 如需了解详情,请参阅 Pub/Sub Java API 参考文档。
Node.js
在尝试此示例之前,请按照《快速入门:使用客户端库》中的 Node.js 设置说明进行操作。如需了解详情,请参阅 Pub/Sub Node.js API 参考文档。
PHP
在尝试此示例之前,请按照《快速入门:使用客户端库》中的 PHP 设置说明进行操作。如需了解详情,请参阅 Pub/Sub PHP API 参考文档。
Python
在尝试此示例之前,请按照《快速入门:使用客户端库》中的 Python 设置说明进行操作。 如需了解详情,请参阅 Pub/Sub Python API 参考文档。
Ruby
在尝试此示例之前,请按照《快速入门:使用客户端库》中的 Ruby 设置说明进行操作。 如需了解详情,请参阅 Pub/Sub Ruby API 参考文档。
Ruby
在试用此示例之前,请按照“Pub/Sub 快速入门:使用客户端库”中的 Ruby 设置说明进行操作。如需了解详情,请参阅 Pub/Sub Ruby API 参考文档。
如需向 Pub/Sub 进行身份验证,请设置应用默认凭据。如需了解详情,请参阅为本地开发环境设置身份验证。
授予 IAM 角色以使用死信主题
如需将无法传送的消息转发到死信主题,Pub/Sub 必须具有执行以下操作的权限:
- 将消息发布到主题。
- 确认消息,这会将其从订阅中移除。
Pub/Sub 会为每个项目创建并维护一个服务账号:service-project-number@gcp-sa-pubsub.iam.gserviceaccount.com
。您可以通过向此服务帐号分配发布者和订阅者角色来授予转发权限。
控制台
如需授予 Pub/Sub 向死信主题发布消息的权限,请完成以下步骤:
在 Google Cloud 控制台中,进入订阅页面。
点击死信主题的订阅的名称。
点击死信标签页。
如需分配发布者角色,请点击授予发布者角色。如果已成功分配发布者角色,您会看到蓝色对勾标记
。如需分配订阅者角色,请点击授予订阅者角色。如果已成功分配发布者角色,您会看到蓝色对勾标记
。
gcloud
如需授予 Pub/Sub 将消息发布到死信主题的权限,请运行以下命令:
PUBSUB_SERVICE_ACCOUNT="service-project-number@gcp-sa-pubsub.iam.gserviceaccount.com" gcloud pubsub topics add-iam-policy-binding dead-letter-topic-name \ --member="serviceAccount:$PUBSUB_SERVICE_ACCOUNT"\ --role="roles/pubsub.publisher"
如需授予 Pub/Sub 确认转发的无法传送的消息的权限,请运行以下命令:
PUBSUB_SERVICE_ACCOUNT="service-project-number@gcp-sa-pubsub.iam.gserviceaccount.com" gcloud pubsub subscriptions add-iam-policy-binding subscription-id \ --member="serviceAccount:$PUBSUB_SERVICE_ACCOUNT"\ --role="roles/pubsub.subscriber"
跟踪传送尝试
为订阅启用死信主题后,来自该订阅的每条消息都有一个字段,用于指定传送尝试次数:
从拉取订阅接收的消息包含
delivery_attempt
字段。从推送订阅接收的消息包含
deliveryAttempt
字段。
以下示例展示了如何获取传送尝试次数:
C++
在尝试此示例之前,请按照《快速入门:使用客户端库》中的 C++ 设置说明进行操作。如需了解详情,请参阅 Pub/Sub C++ API 参考文档。
C#
在试用此示例之前,请按照“Pub/Sub 快速入门:使用客户端库”中的 C# 设置说明进行操作。如需了解详情,请参阅 Pub/Sub C# API 参考文档。
如需向 Pub/Sub 进行身份验证,请设置应用默认凭据。如需了解详情,请参阅为本地开发环境设置身份验证。
Go
在试用此示例之前,请按照“Pub/Sub 快速入门:使用客户端库”中的 Go 设置说明进行操作。如需了解详情,请参阅 Pub/Sub Go API 参考文档。
如需向 Pub/Sub 进行身份验证,请设置应用默认凭据。如需了解详情,请参阅为本地开发环境设置身份验证。
Java
在试用此示例之前,请按照“Pub/Sub 快速入门:使用客户端库”中的 Java 设置说明进行操作。如需了解详情,请参阅 Pub/Sub Java API 参考文档。
如需向 Pub/Sub 进行身份验证,请设置应用默认凭据。如需了解详情,请参阅为本地开发环境设置身份验证。
Node.js
在试用此示例之前,请按照“Pub/Sub 快速入门:使用客户端库”中的 Node.js 设置说明进行操作。如需了解详情,请参阅 Pub/Sub Node.js API 参考文档。
如需向 Pub/Sub 进行身份验证,请设置应用默认凭据。如需了解详情,请参阅为本地开发环境设置身份验证。
PHP
在试用此示例之前,请按照“Pub/Sub 快速入门:使用客户端库”中的 PHP 设置说明进行操作。如需了解详情,请参阅 Pub/Sub PHP API 参考文档。
如需向 Pub/Sub 进行身份验证,请设置应用默认凭据。如需了解详情,请参阅为本地开发环境设置身份验证。
Python
在试用此示例之前,请按照“Pub/Sub 快速入门:使用客户端库”中的 Python 设置说明进行操作。如需了解详情,请参阅 Pub/Sub Python API 参考文档。
如需向 Pub/Sub 进行身份验证,请设置应用默认凭据。如需了解详情,请参阅为本地开发环境设置身份验证。
Ruby
在试用此示例之前,请按照“Pub/Sub 快速入门:使用客户端库”中的 Ruby 设置说明进行操作。如需了解详情,请参阅 Pub/Sub Ruby API 参考文档。
如需向 Pub/Sub 进行身份验证,请设置应用默认凭据。如需了解详情,请参阅为本地开发环境设置身份验证。
当 Pub/Sub 将无法传送的消息转发到死信主题时,它会为消息添加以下属性:
CloudPubSubDeadLetterSourceDeliveryCount
:传送尝试到源订阅的次数。CloudPubSubDeadLetterSourceSubscription
:来源订阅的名称。CloudPubSubDeadLetterSourceSubscriptionProject
:包含源订阅的项目的名称。CloudPubSubDeadLetterSourceTopicPublishTime
:消息最初发布时的时间戳。CloudPubSubDeadLetterSourceDeliveryErrorMessage
:消息无法传送到原始目的地的原因。该属性仅适用于导出订阅。
监控转发的邮件
转发无法送达的消息后,Pub/Sub 服务会从订阅中移除消息。您可以使用 Cloud Monitoring 监控转发的消息。
如果您将订阅附加到死信主题,则这些消息会使用附加订阅的到期政策,而非具有死信主题属性的订阅的有效期。
subscription/dead_letter_message_count
指标用于记录 Pub/Sub 从订阅转发的无法传送的消息数量。
如需了解详情,请参阅监控转发的无法传送的消息。
移除死信主题
如需停止转发无法传送的消息,请从订阅中移除死信主题。
您可以使用 Google Cloud 控制台、Google Cloud CLI 或 Pub/Sub API 从订阅中移除死信主题。
控制台
如需从订阅中移除死信主题,请完成以下步骤:
在 Google Cloud 控制台中,进入订阅页面。
在订阅列表中,点击订阅旁边的 more_vert 进行更新。
从上下文菜单中选择修改。
在死信部分,清除启用死信。
点击更新。
gcloud
如需从订阅中移除死信主题,请使用 gcloud pubsub subscriptions update
命令和 --clear-dead-letter-policy
标志:
gcloud pubsub subscriptions update subscription-id \ --clear-dead-letter-policy
C++
在尝试此示例之前,请按照《快速入门:使用客户端库》中的 C++ 设置说明进行操作。如需了解详情,请参阅 Pub/Sub C++ API 参考文档。
C#
在尝试此示例之前,请按照《快速入门:使用客户端库》中的 C# 设置说明进行操作。 如需了解详情,请参阅 Pub/Sub C# API 参考文档。
Go
在尝试此示例之前,请按照《快速入门:使用客户端库》中的 Go 设置说明进行操作。 如需了解详情,请参阅 Pub/Sub Go API 参考文档。
Java
在尝试此示例之前,请按照《快速入门:使用客户端库》中的 Java 设置说明进行操作。 如需了解详情,请参阅 Pub/Sub Java API 参考文档。
Node.js
在尝试此示例之前,请按照《快速入门:使用客户端库》中的 Node.js 设置说明进行操作。如需了解详情,请参阅 Pub/Sub Node.js API 参考文档。
PHP
在尝试此示例之前,请按照《快速入门:使用客户端库》中的 PHP 设置说明进行操作。如需了解详情,请参阅 Pub/Sub PHP API 参考文档。
Python
在尝试此示例之前,请按照《快速入门:使用客户端库》中的 Python 设置说明进行操作。 如需了解详情,请参阅 Pub/Sub Python API 参考文档。
Ruby
在尝试此示例之前,请按照《快速入门:使用客户端库》中的 Ruby 设置说明进行操作。 如需了解详情,请参阅 Pub/Sub Ruby API 参考文档。
Ruby
在试用此示例之前,请按照“Pub/Sub 快速入门:使用客户端库”中的 Ruby 设置说明进行操作。如需了解详情,请参阅 Pub/Sub Ruby API 参考文档。
如需向 Pub/Sub 进行身份验证,请设置应用默认凭据。如需了解详情,请参阅为本地开发环境设置身份验证。
价格
Pub/Sub 服务转发无法传送的消息时,您需要支付以下费用:
- 向与包含死信主题的项目相关联的结算账号计入的发布费用。
- 出站消息的订阅费用,该费用会结算到与包含死信主题属性的订阅的项目相关联的结算帐号。
如果您设置了订阅的死信主题属性,但死信主题的消息存储位置政策不允许包含该订阅的区域,则出站消息的发布费用也适用。
出站消息的发布费用将计入包含死信主题的项目中。如需了解详情,请参阅价格。