Azure 服务总线会话 FIFO - 消费者应如何处理处理错误?

Azure Service Bus Session FIFO - How Should Consumers Handle Processing Errors?

请您建议如何处理 Azure 服务总线订阅设置中的消费者错误,以确保使用会话 ID 进行 FIFO 处理? (见 https://docs.microsoft.com/en-us/azure/service-bus-messaging/message-sessions#first-in-first-out-fifo-pattern

举个例子,想象一个客户管理系统发布由会计系统使用的消息。所有消息都将会话 ID 作为拥有实体的 AccountID,因此从总线接收的消息在每个 AccountID 的范围内按 FIFO 顺序排列。

想象一下这个消息场景:

如果消息的消费者在 AccountID=1234 上有会话锁,在 T2 的队列上为 AddCustomer 消息获取 PeekLock,然后遭遇会计系统的暂时性故障,他们无法添加客户5678.消费者应该做什么?

如果他们将 AddCustomer 消息设为死信,他们将无法继续处理 RaiseInvoice 消息,因为这将失败,因为会计系统中不存在客户 5678。

如果他们放弃 AddCustomer,那么他们是否会循环 AddCustomer->fail->abondon->AddCustomer 直到达到最大传递计数消息,然后消息变成死信。

消费者应该怎么做才能安全地回应问题?

请参阅 以确认总线的行为方式。我的问题是给定这个问题的知识,消费者应该怎么办?

如果是暂时性故障,那么您有两种选择,一种是自己捕获异常并重试处理。这就是 Azure 函数、masstransit 和 nservicebus 等框架所做的。他们捕捉到你的异常,然后用同样的信息再次给你打电话。 非常短暂的异常情况可能会在那个时候恢复。

下一个选项是故意放弃邮件。这会将其放回队列中,并将重新交付。这将增加每次的交付计数。希望暂时性故障在达到最大传送计数之前解决。否则,它将成为死字,这并不理想。

所以你还可以做的是在发生消息处理错误时拆除整个消费者。这将使会话能够重新分配给另一个消费者,并且重新交付会对他们产生影响,希望他们会有错误。

基本上,您需要重试 and/or 以某种方式等待,直到瞬态条件消失。您可以在重试之间进行指数退避(新的客户端库应在此处自动扩展您的锁定),或者在拆除消费者之前进行延迟。

如果当您说暂时性错误时您指的是持续一个小时或更长时间的错误,您可能需要监视错误并暂停系统的整个部分(禁用队列的所有使用者)直到您恢复了所有错误坏了。

这种故障建模是构建可靠系统的主要挑战。这也是一种乐趣。