死信主题

订阅者可能因各种原因而无法处理消息。例如,在检索处理消息所需的数据时,可能会出现暂时性问题。或者,消息的格式可能不是订阅者预期的格式。

为了管理订阅者无法确认的无法传送的消息,Pub/Sub 可以将这些消息转发到死信主题(也称为死信队列)。

准备工作

  • 为死信主题配置创建主题

    或者,如果您按照本页上的所有说明从头到尾操作,则可以在后续步骤中创建主题。

所需的角色

如需获得管理主题和订阅所需的权限,请让您的管理员为您授予项目的 Pub/Sub Editor (roles/pubsub.editor) IAM 角色。如需详细了解如何授予角色,请参阅管理对项目、文件夹和组织的访问权限

您也可以通过自定义角色或其他预定义角色来获取所需的权限。

您可以在项目级层和个别资源级层配置访问权限控制。您可以在一个项目中创建订阅,并将其附加到位于另一个项目中的主题。确保您拥有每个项目所需的权限。

死信主题的运作方式

如果订阅者应用无法确认消息,Pub/Sub 会重试传送,直到确认时限到期或消息过期。在尝试传送消息的次数达到大致配置的次数后,Pub/Sub 可以将无法传送的消息转发到死信主题。

当 Pub/Sub 转发无法传送的消息时,它会将原始消息封装在新消息中,并添加用于标识源订阅的属性。然后,该消息会被发送到指定的死信主题。附加到死信主题的单独订阅随后可以接收这些转发的消息,以供分析和离线调试。

传送尝试次数上限的计算方式

仅当死信主题配置正确且包含正确的 IAM 权限时,Pub/Sub 才会统计传送尝试次数。

传送尝试次数上限是近似值,因为 Pub/Sub 会尽力转发无法传送的消息。该服务可能会在尝试次数少于配置的次数后转发消息,也可能会在转发前再尝试传送几次。

消息的跟踪传送尝试次数也可能会重置为零,尤其是对于具有不活跃订阅者的拉取订阅。因此,消息传送给订阅者客户端的次数可能会超过配置的传送尝试次数上限。

死信主题属性

您可以为死信主题设置以下订阅属性。

  • 传送尝试次数上限:一个数值,表示 Pub/Sub 为特定消息进行的传送尝试次数。如果订阅者客户端在配置的传送尝试次数内无法确认消息,则该消息会被转发到死信主题。

    • 默认值 = 5
    • 最大值 = 100
    • 最小值 = 5
  • 含有死信主题的项目:如果死信主题与订阅位于不同项目中,则您必须指定含有死信主题的项目。将死信主题设置为与订阅附加到的主题不同的主题。

配置死信主题

以下步骤描述了使用死信主题的工作流。

  1. 创建一个主题(用作死信主题)。

  2. 为死信主题创建订阅。

  3. 为您的订阅启用死信

  4. 将您之前创建的主题附加到订阅。

  5. 向您的 Pub/Sub 服务账号授予使用死信主题所需的角色

创建要与死信主题搭配使用的主题

如果您已创建要用于订阅的主题,则可以跳过此步骤。

  1. 在 Google Cloud 控制台中,前往主题页面。

    打开“主题”

  2. 点击创建主题

  3. 输入主题 ID,例如 my-test-topic

  4. 保留默认订阅的选项,然后点击创建

为订阅设置死信主题

您可以为新订阅或现有订阅设置死信主题。

为新订阅设置死信主题

您可以使用Google Cloud 控制台、Google Cloud CLI、客户端库或 Pub/Sub API 创建订阅并设置死信主题。

控制台

如需创建订阅并设置死信主题,请完成以下步骤:

  1. 在 Google Cloud 控制台中,前往订阅页面。

    前往订阅页面

  2. 点击创建订阅

  3. 输入订阅 ID

  4. 选择您要用于订阅的主题。订阅将接收来自该主题的消息。这不是您的死信主题。 您将在下一步中选择此选项。

  5. 死信部分,选择启用死信

  6. 从下拉菜单中选择死信主题。

    如果所选的死信主题没有订阅,系统会提示您创建一个订阅。

  7. 最大传送尝试次数字段中,指定一个 5 到 100 之间的整数。

  8. 点击创建

  9. 点击“详细信息”面板,以确定任何可能的操作项。如果任何项目显示错误图标 ,请点击待办项以解决问题。

    “死信”标签页,其中包含一些待办项。

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 参考文档

namespace pubsub = ::google::cloud::pubsub;
namespace pubsub_admin = ::google::cloud::pubsub_admin;
[](pubsub_admin::SubscriptionAdminClient client,
   std::string const& project_id, std::string const& topic_id,
   std::string const& subscription_id,
   std::string const& dead_letter_topic_id,
   int dead_letter_delivery_attempts) {
  google::pubsub::v1::Subscription request;
  request.set_name(
      pubsub::Subscription(project_id, subscription_id).FullName());
  request.set_topic(pubsub::Topic(project_id, topic_id).FullName());
  request.mutable_dead_letter_policy()->set_dead_letter_topic(
      pubsub::Topic(project_id, dead_letter_topic_id).FullName());
  request.mutable_dead_letter_policy()->set_max_delivery_attempts(
      dead_letter_delivery_attempts);
  auto sub = client.CreateSubscription(request);
  if (sub.status().code() == google::cloud::StatusCode::kAlreadyExists) {
    std::cout << "The subscription already exists\n";
    return;
  }
  if (!sub) throw std::move(sub).status();

  std::cout << "The subscription was successfully created: "
            << sub->DebugString() << "\n";

  std::cout << "It will forward dead letter messages to: "
            << sub->dead_letter_policy().dead_letter_topic() << "\n";

  std::cout << "After " << sub->dead_letter_policy().max_delivery_attempts()
            << " delivery attempts.\n";
}

C#

在尝试此示例之前,请按照《快速入门:使用客户端库》中的 C# 设置说明进行操作。 如需了解详情,请参阅 Pub/Sub C# API 参考文档


using Google.Cloud.PubSub.V1;
using System;

public class CreateSubscriptionWithDeadLetterPolicySample
{
    public Subscription CreateSubscriptionWithDeadLetterPolicy(string projectId, string topicId, string subscriptionId, string deadLetterTopicId)
    {
        SubscriberServiceApiClient subscriber = SubscriberServiceApiClient.Create();
        // This is the subscription you want to create with a dead letter policy.
        var subscriptionName = SubscriptionName.FromProjectSubscription(projectId, subscriptionId);
        // This is an existing topic that you want to attach the subscription with dead letter policy to.
        var topicName = TopicName.FromProjectTopic(projectId, topicId);
        // This is an existing topic that the subscription with dead letter policy forwards dead letter messages to.
        var deadLetterTopic = TopicName.FromProjectTopic(projectId, deadLetterTopicId).ToString();
        var subscriptionRequest = new Subscription
        {
            SubscriptionName = subscriptionName,
            TopicAsTopicName = topicName,
            DeadLetterPolicy