azure - Azure 服务总线在重试消息之前是否可以延迟?

标签 azure azureservicebus

Azure 服务总线支持内置重试机制,使废弃的消息立即可见以供另一次读取尝试。我正在尝试使用此机制来处理一些暂时性错误,但该消息在被放弃后立即可用。

我想做的是让消息在被放弃后的一段时间内不可见,最好基于指数递增的策略。

我尝试在放弃消息时设置 ScheduledEnqueueTimeUtc 属性,但似乎没有效果:

var messagingFactory = MessagingFactory.CreateFromConnectionString(...);

var receiver = messagingFactory.CreateMessageReceiver("test-queue");

receiver.OnMessageAsync(async brokeredMessage =>
{
    await brokeredMessage.AbandonAsync(
        new Dictionary<string, object>
        {
            { "ScheduledEnqueueTimeUtc", DateTime.UtcNow.AddSeconds(30) }
        });
    }
});

我考虑过根本不放弃消息,只是让锁过期,但这需要有某种方法来影响 MessageReceiver 如何指定消息的锁定持续时间,我可以在 API 中找不到任何可以让我更改此值的内容。此外,在需要锁定之前,无法读取消息的传递计数(因此无法决定等待下一次重试的时间)。

消息总线中的重试策略是否会受到某种方式的影响,或者是否可以通过其他方式人为地引入延迟?

最佳答案

这里要小心,因为我认为您将重试功能与用于 OnMessage 事件驱动消息处理的自动 Complete/Abandon 机制混淆了。当对服务总线的调用失败时,内置的重试机制就会发挥作用。例如,如果您调用将消息设置为完成并且失败,则重试机制将启动。如果您正在处理消息,您自己的代码中会发生异常,该异常不会通过重试功能触发重试。您的问题没有明确说明错误是否来自您的代码或尝试联系服务总线时。

如果您确实修改了尝试与服务总线通信时发生错误时发生的重试策略,则可以修改 MessageReciver 上设置的 RetryPolicy本身。默认情况下使用一个 RetryExponitial ,以及一个您可以创建自己的抽象 RetryPolicy

我认为您想要的是更好地控制当您在处理过程中遇到异常时会发生什么,并且您想推迟处理该消息。有几个选项:

当您创建消息处理程序时,您可以设置 OnMessageOptions 。属性之一是“自动完成”。默认情况下,此设置为 true,这意味着一旦消息处理完成,就会自动调用 Complete 方法。如果发生异常,则会自动调用放弃,这就是您所看到的。通过将 AutoComplete 设置为 false,您需要从消息处理程序中自行调用 Complete。如果不这样做,将导致消息锁最终耗尽,这是您正在寻找的行为之一。

因此,您可以编写处理程序,以便在处理过程中发生异常时,您只需调用 Complete 即可。然后,该消息将保留在队列中,直到锁耗尽,然后再次可用。应用标准的死信机制,在尝试 x 次后,它将自动放入死信队列。

以这种方式处理的一个注意事项是任何类型的异常都将以这种方式处理。您确实需要考虑什么类型的异常正在执行此操作以及您是否确实想推迟处理。例如,如果您在处理过程中调用第三方系统,并且它给您一个您知道是暂时的异常,那就太好了。但是,如果它给您一个错误,您知道这将是一个大问题,那么您可能会决定在系统中执行其他操作,而不仅仅是保留该消息。

您还可以查看“Defer”方法。该方法实际上不允许该消息从队列中处理,除非它是通过其序列号专门拉取的。您的代码必须记住序列号值并提取它。但这并不完全是您所描述的。

另一个选择是您可以放弃 OnMessage、事件驱动的消息处理方式。虽然这非常有帮助,但您无法对事情进行太多控制。相反,连接您自己的处理循环并自行处理放弃/完成。您还需要处理 OnMessage 模式为您提供的一些线程/并发调用管理。这可能需要更多工作,但您拥有最大的灵 active 。

最后,我相信您对 AbandonAsync 进行的调用传递您想要修改的属性不起作用的原因是这些属性引用 Metadata properties在方法上,而不是 BrokeredMessage 上的标准属性。

关于azure - Azure 服务总线在重试消息之前是否可以延迟?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21536722/

相关文章:

Azure服务总线队列: re-schedule messages while increasing deliveryCount

Azure 服务总线速度

c# - 查看没有事件消息的 session 启用主题/订阅时出现超时异常

azure - 使用 ServiceBusProcessor 时出错 - Azure.Messaging.ServiceBus SDK

Azure DevOps - 服务主体不工作

azure - Paypal IPN 返回 302

c# - 完成锁定消息时出现 Azure 服务总线 MessageLockLostException

azure - 在Python中使用Azure Face Api,如果在视频流中检测到同一个人,如何返回单个faceId或一组FaceId?

azure - 将 Cosmos DB 模拟器 (MongoDB API) 迁移到 Azure 时发生 fatal error

azure - 在 Azure Function 中访问 Azure Key Vault secret