重试请求

发布失败通常是由客户端瓶颈导致的,例如服务 CPU 不足,线程运行状况不佳或网络拥塞。发布者重试政策定义了 Pub/Sub 尝试传送消息的次数以及每次尝试之间的时间长度。

本文档介绍了如何将重试请求与发布到主题的消息搭配使用。

准备工作

在配置发布工作流之前,请确保您已完成以下任务:

所需角色

如需获得重试向主题发送消息请求所需的权限,请让您的管理员向您授予主题的Pub/Sub 发布者 (roles/pubsub.publisher) IAM 角色。如需详细了解如何授予角色,请参阅管理对项目、文件夹和组织的访问权限

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

您需要额外的权限才能 创建或更新主题和订阅。

重试请求简介

重试设置控制 Pub/Sub 客户端库重试发布请求的方式。客户端库具有以下重试设置:

  • 初始请求超时:客户端库 停止等待初始发布请求完成前的时间。
  • 重试延迟:请求超时后,客户端库等待请求重试的时间。
  • 总超时:客户端库停止重试发布请求后的时间量。

如需重试发布请求,初始请求超时必须短于总超时。例如,如果您使用的是指数退避算法,客户端库会按如下所示计算请求超时和重试延迟:

  • 每个发布请求后,请求超时会以请求超时倍数增加,最长为请求超时上限。
  • 每次重试后,重试延迟时间会以重试延迟倍数增加,最长为重试延迟上限。

重试消息请求

在发布过程中,您可能会看到暂时性或永久性发布失败。对于暂时性错误,您通常无需采取任何特殊操作,因为 Pub/Sub 会自动重试消息。

当发布操作成功,但发布者客户端未及时收到发布响应时,也可能会发生错误。在这种情况下,系统也会重试发布操作。因此,您可能会收到两条内容相同但消息 ID 不同的消息。

如果出现持续性错误,请考虑在发布过程之外实现适当的操作,以避免 Pub/Sub 负载过重。

如果发布失败,系统会自动重试,但无法保证能够重试的错误除外。此示例代码演示了如何使用自定义 重试设置创建发布者(请注意,并非所有客户端库都支持自定义重试 设置;请参阅适用于您所选语言的API 参考文档 ):

C++

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

namespace pubsub = ::google::cloud::pubsub;
using ::google::cloud::future;
using ::google::cloud::Options;
using ::google::cloud::StatusOr;
[](std::string project_id, std::string topic_id) {
  auto topic = pubsub::Topic(std::move(project_id), std::move(topic_id));
  // By default a publisher will retry for 60 seconds, with an initial backoff
  // of 100ms, a maximum backoff of 60 seconds, and the backoff will grow by
  // 30% after each attempt. This changes those defaults.
  auto publisher = pubsub::Publisher(pubsub::MakePublisherConnection(
      std::move(topic),
      Options{}
          .set<pubsub::RetryPolicyOption>(
              pubsub::LimitedTimeRetryPolicy(
                  /*maximum_duration=*/std::chrono::minutes(10))
                  .clone())
          .set<pubsub::BackoffPolicyOption>(
              pubsub::ExponentialBackoffPolicy(
                  /*initial_delay=*/std::chrono::milliseconds(200),
                  /*maximum_delay=*/std::chrono::seconds(45),
                  /*scaling=*/2.0)
                  .clone())));

  std::vector<future<bool>> done;
  for (char const* data : {"1", "2", "3", "go!"}) {
    done.push_back(
        publisher.Publish(pubsub::MessageBuilder().SetData(data).Build())
            .then([](future<StatusOr<std::string>> f) {
              return f.get().ok();
            }));
  }
  publisher.Flush();
  int count = 0;
  for (auto& f : done) {
    if (f.get()) ++count;
  }
  std::cout << count << " messages sent successfully\n";
}

C#

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


using Google.Api.Gax.Grpc;
using Google.Cloud.PubSub.V1;
using Grpc.Core;
using System;
using System.Threading.Tasks;

public class PublishMessageWithRetrySettingsAsyncSample
{
    public async Task PublishMessageWithRetrySettingsAsync(string projectId, string topicId, string messageText)
    {