Azure Service Bus Queue 如何保证最多一次交付?

Posted

技术标签:

【中文标题】Azure Service Bus Queue 如何保证最多一次交付?【英文标题】:How does Azure Service Bus Queue guarantees at most once delivery? 【发布时间】:2018-12-02 00:49:00 【问题描述】:

据此doc服务总线支持Receive-and-Delete和Peek-Lock两种模式。

如果使用 Peek-Lock 模式,如果消费者在处理消息后立即崩溃/挂起/执行很长时间的 GC,但在 messageId 为“已完成”且可见性时间到期之前,同一消息有可能被传递两次。

那么微软怎么说Service Bus最多支持一次交付模式。是不是因为接收和删除模式只发送一次消息。但话又说回来,如果消费者在处理消息时发生了一些事情,那么有价值的信息就会丢失。

如果是,那么使用 Azure 服务总线作为队列和 Azure 函数作为消费者来确保准确的一次交付的最佳方法是什么。

附:我能想到的一种方法是将 MessageID 存储在 blob 中,但在我的情况下,MessageID 的数量可能非常大,存储和加载所有这些不是正确的方法。

【问题讨论】:

【参考方案1】:

Azure Functions 将始终在 Peek-Lock 模式下使用服务总线消息。 Exactly Once 在一般情况下基本上是不可能的:在完成消息之前,消费应用程序总是有可能在错误的时间崩溃,然后消息将被重新传递。

您应该努力实施 Effectively Once 处理。这通常通过幂等消息处理器来实现。

存储 MessageID(消费者端重复数据删除)是一种选择。您可以制定一个清理旧消息 ID 的策略,以使此类存储的大小保持可管理。为了使这个 100% 可靠,您必须将消息 ID 存储在与处理器完成的其他修改相同的事务中。

其他选项实际上取决于您的处理方案。找到一种方法使其具有幂等性 - 使多次处理同一消息在功能上与只处理一次相同。

【讨论】:

其他选项是什么。在我的场景中,我正在使用来自服务总线的路径,Azure 函数使用该路径下载 blob,按摩数据并通过 HTTP 发送到外部服务。成功时它会从服务总线中删除消息。 在这种情况下,外部服务必须能够对您的请求进行重复数据删除,例如通过检查是否已经存在具有相同 blob 路径/id 的数据 我无法控制外部服务。顺便问一下,为什么我们不能在 azure 函数中应用重复数据删除逻辑? 因为你的外部服务调用可能会失败,你不知道它是否真的成功

以上是关于Azure Service Bus Queue 如何保证最多一次交付?的主要内容,如果未能解决你的问题,请参考以下文章

Azure Integration with Dynamics 365 CE/ CRM using Service Bus, Queue, Plugin Registration Tool

Azure Integration with Dynamics 365 CE/ CRM using Service Bus, Queue, Plugin Registration Tool

Azure Integration with Dynamics 365 CE/ CRM using Service Bus, Queue, Plugin Registration Tool

NodeJs &.net core connect Azure service bus

Configure Dynamics 365 and Azure Service Bus Integration (using OneWay relay and listener)

C# 消息队列-Microsoft Azure service bus 服务总线