预提取 Azure 服务总线消息
预提取功能用于在后台提取消息到本地预提取缓冲区,直到达到预提取计数上限。 从缓冲区提供消息。 消息从缓冲区取出后,缓冲区中的空间便被释放出来,接收者就可以在后台预提取更多消息。
若要启用预提取功能,请将队列或订阅客户端的预提取计数设置为大于零的数字。 将该值设为零可关闭预提取。 如果该功能关闭后预提取缓冲区中还有信息,则应用程序将首先从缓冲区接收这些消息,然后才会转向服务。
在 ServiceBusReceiverOptions 和 ServiceBusProcessorOptions 对象上设置预提取计数属性。
注意
Java 脚本 SDK 不支持预提取功能。
尽管消息在预提取缓存区中提供,但后续接收的任何调用均可立即从缓冲区完成。 空间可用时,系统将在后台对缓冲区进行补充。 如果没有消息用于传送,接收操作将清空缓存区,并按预期进行等待或阻止。
预提取为何不是默认选项?
预提取可加快消息流,方法是在应用程序请求消息前,先准备好用于本地检索的消息。 这种吞吐量提升是应用程序作者不得不明确作出的某种权衡的结果。
使用“接收-删除”模式时,所有进入预取缓冲区的消息在队列中将不再可用。 消息仅保留在内存预提取缓冲区中,直到系统将其接收到应用程序中。 如果在应用程序接收到消息前终止应用程序,这些消息将丢失,且不可恢复。
在“Peek-Lock(查看-锁定)接收模式下,从预取缓存区中取出的消息将以锁定状态进入缓存区。 锁定计时器自消息预提取到缓冲区起开始计时。 如果预提取缓存区很大且所需处理时间过长,以致消息于锁在预提取缓冲区时,甚至于应用程序处理消息时过期,则应用程序可能需要处理出现的一些混乱事件。 应用程序可能收到包含到期或即将到期的锁定的消息。 如有收到,应用程序可能会处理该消息,但随后发现其因锁定到期而无法完成处理。 应用程序可查看 LockedUntilUtc
属性,但请记住,代理时钟和本地计算机时钟之间存在时钟偏差。
如果锁定在预提取缓冲区静默地到期,则视为已放弃该消息,且可再次将消息用于从队列进行检索。 然后,消息会再次提取到预提取缓冲区中,并置于末端。如果在消息过期期间,预提取缓冲区通常无法使用,则将导致重复预提取消息,但始终无法将其以可用(有效锁定)状态有效送达,并最终在超出最大传送数后移动到死信队列。
如果应用程序显式放弃消息,该消息可能再次可用于从队列中检索。 启用预取功能后,该消息会再次被提取到预取缓冲区中,并放置在末尾。 由于来自预提取缓冲区的消息按先入先出 (FIFO) 顺序排空,应用程序可能会无序地接收消息。 例如,应用程序可能会从缓冲区收到 ID 为 2 的消息,然后收到 ID 为 1 的消息(之前已放弃)。
如果消息处理需要高度可靠性,且处理需要花费大量精力和时间,则建议谨慎使用或者避免使用预提取功能。 如果需要较高吞吐量且消息处理通常比较便宜,则预提取会产生显著的吞吐量优势。
需要均衡对队列或订阅配置的最大预提取数和锁定持续时间,以便锁定超时至少超出最大预提取缓存区大小外加一条消息的累积预期消息处理时间。 同时,锁定持续时间不应太长,以免消息在锁定时超过其最大生存时间,因为这意味着,如果它们在预提取时无法补全,它们就会被删除。
注意
2026 年 9 月 30 日,我们将停用 Azure 服务总线 SDK 库 WindowsAzure.ServiceBus、Microsoft.Azure.ServiceBus 和 com.microsoft.azure.servicebus,这些库不符合 Azure SDK 准则。 我们还将结束对 SBMP 协议的支持,因此在 2026 年 9 月 30 日之后,你将无法再使用此协议。 请在该日期之前迁移到最新的 Azure SDK 库,新库提供了关键安全更新和改进功能。
尽管旧库在 2026 年 9 月 30 日之后仍可使用,但它们将不再获得 Azure 的官方支持和更新。 有关详细信息,请参阅支持停用公告。