在发布过程中,发布者客户端向 Pub/Sub 主题发送消息。以下是向 Pub/Sub 发布消息的一些最佳实践。
本文档假定您已熟悉向 Pub/Sub 主题发布消息的过程。
如果您刚接触 Pub/Sub,请参阅其中一个快速入门指南,了解如何使用控制台、gcloud CLI 或客户端库运行 Pub/Sub。
根据发布操作的响应采取行动
当高级客户端库的发布调用完成时,它会返回一个包含操作结果的 future 对象。为避免阻塞单个发布请求,请异步处理结果。您应根据自己的应用场景,确定处理失败的最佳方式。支持无线更新的选项包括:
- 记录错误,不执行任何其他操作(如果您的用例不需要成功发布所有消息)。
- 在可能发生暂时性故障(例如
Deadline exceeded错误)时重试发布。 - 将消息持久保存到文件或存储区,以便稍后重试发布,尤其是在出现需要用户干预的错误(例如
Not found或Permission denied)时。 - 将错误传播到向您发送您尝试发布的消息的上游服务。
如果您认为 Pub/Sub 未按预期向订阅者传递消息,请验证您是否在跟踪发布结果,以及发布是否成功。
如果发布成功,则发布调用的结果是已发布消息的消息 ID。
保留消息 ID
为了更轻松地进行问题排查,发布者和订阅者应保留已发布消息的消息 ID。您可以存储每条已发布消息的 ID,也可以根据需要启用消息 ID 日志记录。保留消息 ID 有助于更轻松地排查重复消息、重新传送、数据丢失和其他常见问题。如需了解详情,请参阅处理重复项。
请先附加订阅或启用主题保留,然后再开始发布
如果您开始发布到没有附加订阅者的主题,则消息不会保留。这些消息无法传递到随后附加的订阅。因此,在开始发布消息之前,请执行以下操作之一:
将订阅附加到主题。选择以下方法之一:
创建订阅,并在创建过程中指定主题。了解如何创建拉取订阅、推送订阅、BigQuery 订阅或 Cloud Storage 订阅。
启用主题消息保留功能。
主题消息保留可让订阅重放您创建订阅之前发布的消息。如果启用了主题消息保留,则主题保留的消息的存储费用将计入主题所在的项目。
配置批量消息传递
在 Pub/Sub 中,批量消息传递是指将多条消息合并为一个批次,并在单个发布请求中发布的过程。如果您使用客户端库发布消息,则默认情况下会启用批处理。消息批处理(或分组)有助于发布者提高效率,并以更高的吞吐量发送消息。批处理可降低发布数据的费用。不过,批处理也会导致单条消息出现延迟,因为发布者会等待批处理填满后再发布。
Pub/Sub 中的延迟时间分为两种类型:
端到端延迟时间是指发布者发布消息并将其传递给相应订阅者进行处理所需的时间。
发布延迟时间是指发布消息所需的时间。
使用批处理时,增加这两种类型的延迟时间是为了提高效率和吞吐量而做出的权衡。
您可以根据消息请求大小、消息数量和时间在客户端库中批量处理消息。配置批处理设置时,您可以根据自己的应用场景,在费用、吞吐量和延迟时间之间找到合适的平衡点。
批量消息传递变量的默认值和变量名称可能因客户端库而异。您可以在客户端库中指定一个或全部三个值。如果满足批量消息传递变量的任何一个值,客户端库就会发布下一批消息。
如需为发布者客户端配置批量消息传递,请参阅在发布请求中批量处理消息。
为瞬时消息峰值配置流控制
如果发布者客户端必须处理大量消息,则发布请求可能会开始在内存中累积,直到消息无法发布并出现 Deadline exceeded 错误。
如需应对发布消息时的瞬时峰值,您可以在发布方设置中使用流控制。发布者端流控制可防止发布者客户端资源因未完成的请求过多而过载。如果发布者客户端在内存、CPU 或线程方面受到限制,则会生成大量 Deadline exceeded 错误。
如需在客户端库中配置流量控制,请为未完成消息数上限和未完成消息字节数上限变量设置适当的值。这些值可平衡消息吞吐量和系统容量。
如需检查您的客户端库是否支持发布者流控制并对其进行配置,请参阅流控制。
了解网络带宽和延迟时间
发布者吞吐量受网络带宽和发送的请求数量限制。如果带宽良好但网络延迟时间较长,您不希望系统因大量小请求而过载。发布商端流量控制有助于解决客户端网络问题。
发布者吞吐量也受 CPU 和内存限制。可用的机器核心越多,您就可以设置更高的线程数,从而提高发布吞吐量。如需进一步了解如何最大限度地提高流式传输性能,请参阅测试 Cloud Pub/Sub 客户端以最大限度地提高流式传输性能。
调整失败发布的重试请求变量
当发布者客户端发布消息时,您可能会看到发布失败。这些故障通常是由客户端瓶颈引起的,例如服务 CPU 不足、线程运行状况不佳或网络拥塞。publisher retry policy 决定了消息传送失败时的行为。重试政策定义了 Pub/Sub 尝试递送消息的次数以及每次尝试之间的时间长度。
例如,在 Pub/Sub 的 Java 客户端库中,发布者客户端包含以下值:
initialRetryDelay。发布者在重试发布操作之前等待的初始延迟时间。默认值为
100 milliseconds。retryDelayMultiplier。用于计算重试之间延迟时间的乘法因子。默认值为
4。这意味着,第二次重试的延迟时间最长为100 milliseconds * 4 = 400 milliseconds,第三次重试的延迟时间最长为400 milliseconds * 4 = 1600 milliseconds。maxRetryDelay。发布者在重试发布操作之前等待的最长延迟时间。默认值为
60 seconds。initialRpcTimeout。发布者等待 RPC 调用完成的初始超时。默认值为
5 seconds。rpcTimeoutMultiplier。用于计算 RPC 超时时间的乘法因子。默认值为
4.0。这意味着,第二次重试时,RPC 调用的超时时间最长为5 seconds * 4 = 20 seconds,第三次重试时,超时时间最长为10 seconds * 4 = 40 seconds。maxRpcTimeout。发布者等待 RPC 调用完成的最长超时时间。默认值为
600 seconds。totalTimeout。发布操作的总超时。这包括等待 RPC 调用完成所花费的时间以及重试之间的等待时间。默认值为
600 seconds。
只有在发现默认重试设置不适合您的用例时,才调整指定的值。例如,发布大量消息不需要您增加 initialRetryDelay 和 maxRetryDelay 值。但是,您可以在这些情况下调整流控制和批处理。如果您是从不稳定的互联网连接或带宽受限的连接进行发布,则可以尝试使用 initialRpcTimeout、maxRpcTimeout 和 rpcTimeoutMultiplier 变量的值。如需了解建议的值,请参阅发布操作失败,并显示 DEADLINE_EXCEEDED。
使用消息存储政策确保数据本地性
Pub/Sub 的主题消息存储政策提供了一种方法,可确保发布到主题的消息永远不会保留在您指定的一组Google Cloud 区域之外,无论发布请求来自何处。
使用消息存储政策指定允许 Pub/Sub 在磁盘上存储消息数据的 Google Cloud 区域列表。当消息发布到不在此列表中的区域时,请求会转发到最近的允许区域进行处理。该政策可以配置在主题上,也可以配置为项目、项目文件夹或整个组织的组织政策。配置组织政策后,只能以不违反组织政策的方式更改单个主题政策。
例如,在欧洲运营的公司可能会使用消息存储政策来确保所有数据都存储在欧盟区域,以遵守当地法律。
如需了解详情,请参阅配置消息存储政策。
发布中有序消息传递的最佳实践
如果您使用消息排序,请确保满足以下条件:
使用位置端点。消息的顺序会在发布端和区域内保留。换句话说,如果您要将消息发布到多个区域,则只有同一区域内的消息才会以一致的顺序传递。如果您的消息全部发布到同一区域,但订阅者分布在不同区域,则订阅者会按顺序接收所有消息。使用位置端点将消息发布到同一区域。
配置恢复发布函数。当客户端库重试请求且消息具有排序键时,客户端库会重复重试请求,而不管重试设置如何。如果发生不可重试的错误,客户端库不会发布该消息,并会停止发布具有相同排序键的其他消息。当您准备好继续在发布失败的排序键上发布时,请调用
resumePublish方法。
最佳做法摘要
下表总结了本文档中建议的最佳做法。
| 主题 | 任务 |
|---|---|
| 配置消息保留 | 在发布或启用消息保留之前,请先附加订阅。 |
| 在发布请求中批量处理消息 | 对消息进行批处理或分组,以提高发布者的效率并以更高的吞吐量发送消息。 |
| 流控制 | 在发布方设置中配置流控制,以处理瞬时流量峰值。 |
| 测试 Pub/Sub 客户端以最大限度地提高流式传输性能 | 通过增加可用的机器核心和网络带宽来扩缩发布者吞吐量。 |
| 重试请求 | 只有在发现默认设置不适合您的用例时,才调整发布者重试政策的指定值。 |
| 配置消息存储政策 | 使用消息存储政策,仅在特定位置将消息数据存储在磁盘上。 |
| 在发布中使用排序键时,请使用位置端点 | 使用有序消息传递时,请使用位置端点,并为发布失败配置恢复发布函数。 |