订阅 Pub/Sub 主题的最佳实践

在订阅过程中,订阅方客户端接收来自 Pub/Sub 主题的消息。下面列出了一些订阅 Pub/Sub 的最佳实践。

本文档假设您已熟悉订阅 Pub/Sub 主题并在订阅方客户端中接收消息的过程。

如果您是 Pub/Sub 新手,请参阅其中一个快速入门指南,了解如何使用控制台Google Cloud CLI客户端库运行 Pub/Sub。

选择合适的订阅

Pub/Sub 提供标准订阅,例如推送拉取订阅。除了标准订阅之外,Pub/Sub 还提供导出订阅,让您可以将消息直接存储到Trusted Cloud by S3NS 资源,而无需将 Dataflow 用作中介。 例如,BigQuery 订阅会将消息存储在 BigQuery 表中。

建议在以下情况下使用推送订阅:

  • 您不得在订阅者应用中包含任何将客户端库作为依赖项导入的代码。

  • 订阅者客户端无法发出任何出站请求。

  • 您希望使用同一实例来处理来自不同主题和订阅的消息,但订阅者客户端不知道订阅列表。

对于一般情况,我们建议使用高级别客户端库。如果您改为使用一元拉取,请勿将 returnImmediately 设置为 true。将其设置为 true 会对拉取性能产生不利影响。字段 returnImmediately 现已弃用。

在确认消息之前处理消息

默认情况下,Pub/Sub 会在消息被确认后从订阅中舍弃该消息。如果您在发送确认之前未处理消息,并且处理失败,则服务不会重新传送该消息。例外情况是,您已配置保留已确认的消息或主题保留,并且执行了查找操作

如果您有高延迟订阅者,可能需要为流量控制租约管理设置自定义值。

为瞬时流量峰值配置订阅方流控制

订阅者端的流控制功能可让您防止订阅者因流量高峰而过载。这样一来,自动扩缩机制便有时间响应增加的负载,或者可以将负载的处理分散到更长的时间段内。前一种方法可节省延迟时间,后一种方法可节省费用。

如需配置流量控制,您必须为 maximum outstanding messagestotal outstanding message bytes 设置适当的值。这些流量控制变量的默认值和变量名称可能因客户端库而异。

  • 待处理消息数量上限定义了传送给客户端的消息数量上限,对于这些消息,Pub/Sub 尚未收到确认或否定确认。

  • 未处理的消息总字节数是指已传送给客户端但 Pub/Sub 尚未收到确认或否定确认的消息的最大总大小。

如果超出其中一个选项的限制,订阅者客户端将不会拉取更多消息。此行为会一直持续,直到已拉取的消息得到确认或否定确认为止。这样,您就可以在吞吐量与运行更多订阅者相关的费用之间做出权衡。

处理重复的递送

默认情况下,Pub/Sub 会向订阅者至少传送一次消息。这意味着即使消息已确认,也可能会多次传送。以下部分讨论了如何处理常见的重新传送场景。

持续重新传送多条消息

如果您遇到许多消息总是被重新传送的情况,则说明您的订阅者过载,或者他们未在截止时间到期之前确认消息。

如果您使用的是拉取订阅,可能需要设置自定义值来控制流量值,或使用租约管理来增加租约延期期限。

如果您使用的是推送订阅,可能需要增加确认时限设置。您还可以遵循有关如何保持健康的订阅状态的最佳实践。

偶尔重新传送消息

如果您看到消息在确认时限到期之前或在消息被确认后几秒钟内重新传送,则表示 Pub/Sub 的行为符合预期。您不应经常看到这些重新传送高峰,但如果确实发生重新传送,则可能会同时重新传送多条消息。您的系统必须能够容忍这些偶尔出现的重复项。

重复重新传送少量消息

如果您发现少量邮件多次送达,请先确认您是否已确认这些邮件。如果不是,请找出订阅者未正确处理消息的原因。您可能需要配置死信主题,以防止进一步重新传送。如果您确认了该消息,Pub/Sub 可能仍会按预期运行。虽然这种情况非常罕见,但如果出现内部网络或硬件中断,仍有可能导致少量消息多次传送。在这种情况下,服务会尝试自我修复,但修复措施可能需要几分钟才能生效。

您的系统必须能够容忍重新传送。您可以确保尽快处理和确认消息,从而降低出现这种情况的可能性。

如果您的应用无法容忍任何重复项,您可以启用“仅传送一次”功能。请注意,此功能仅适用于拉取订阅,并且还会导致发布-订阅延迟时间更长。在启用此功能之前,请评估更高的延迟时间是否适合您的使用情形。

订阅中的有序消息传递的最佳实践

如果您使用消息排序,请确保以下事项:

  • 选择 StreamingPull 或 Pull 订阅。对于推送订阅,Pub/Sub 每次只支持每个排序键有一条未完成的消息。在此类场景中发送并行推送请求类似于发送多个批次的消息,这些消息具有相同的排序键,可同时拉取订阅者。因此,对于经常发布具有相同排序键的多条消息的主题,或者对于延迟时间非常重要的主题,不建议使用推送订阅。

  • 在订阅中启用消息排序。在发布者端,如果您发送的消息带有排序键且位于同一区域,则可以配置订阅者按顺序接收这些消息。在订阅者端,仅为要接收有序消息的订阅启用消息排序属性。根据属性状态,附加到主题的每个订阅都可以确定是否需要按顺序传送,而不会相互影响。

  • 按顺序确认消息。使用按序传送时,系统不会处理后续消息的确认,直到按排序键处理完之前消息的确认。例如,如果您有 1、2 和 3 这三条消息,它们具有相同的排序键,并且您收到了所有这些消息,但只确认了消息 3,那么在消息 1 和 2 也得到确认之前,服务不会将消息 3 视为已确认。如果从未收到消息 1 和 2 的确认,则消息 1、2 和 3 都会重新传送。

最佳做法摘要

下表总结了本文档中建议的最佳实践:

主题 任务
选择订阅类型 根据您的业务需求选择合适的订阅类型。如果您的订阅支持,请同时使用高级客户端库。
重放已确认的消息 在确认消息之前处理消息。或者,配置为执行查找操作,以免丢失已确认的消息。
流控制 在订阅者设置中配置流控制,以确保在自动扩缩启动或时间过去之前,订阅者不会过载。
订购消息 使用有序的消息传递时,请选择 StreamingPull 或 Pull,在订阅中启用消息排序,并按顺序确认消息。

后续步骤