c# - "MaxAutoRenewDuration"在azure服务总线中的作用是什么?

标签 c# azure .net-core azureservicebus

我正在使用Microsoft.Azure.ServiceBus。 (doc)

我遇到了以下异常:

The lock supplied is invalid. Either the lock expired, or the message has already been removed from the queue.

通过这些问题的帮助:

1 , 2 , 3 ,

我可以通过将自动完成设置为false并将Azure的队列锁定持续时间增加到其最大值(从30 秒到 5 分钟)。

_queueClient.RegisterMessageHandler(ProcessMessagesAsync, new 
                         MessageHandlerOptions(ExceptionReceivedHandler)
                         {
                             MaxConcurrentCalls = 1,
                             MaxAutoRenewDuration = TimeSpan.FromSeconds(10),
                             AutoComplete = false
                         }
);

private async Task ProcessMessagesAsync(Message message, CancellationToken token)
{
    await ProccesMessage(message);
}

private async Task ProccesMessage(Message message)
{
    //The complete should be closed before long-timed process
    await _queueClient.CompleteAsync(message.SystemProperties.LockToken);
    await DoFoo(message.Body); //some long running process
}

我的问题是:

    1. 这个answer建议引发异常,因为锁定在长时间进程之前已过期,但在我的情况下,我立即将消息标记为完成(在长时间运行进程之前),所以我不确定为什么要更改锁定持续时间 azure 有什么区别吗?当我将其改回 30 秒时,我可以再次看到异常。
  • 不确定它是否与问题相关,但目的是什么MaxAutoRenewDuration,官方文档是自动更新锁的最大持续时间。。如果在我的情况下,我只有一个应用程序接收器从该队列中排队,那么是否不需要它,因为我不需要锁定来自另一个应用程序的消息来捕获它?为什么这个值要大于最长消息锁定持续时间?

最佳答案

您需要考虑一些事项。

  1. 锁定持续时间
  2. 自从代理获取消息以来的总时间

锁定持续时间很简单 - 单个竞争消费者可以租用一条消息的时间,而无需将该消息租给任何其他竞争消费者。

总时间有点诡异。注册用于接收消息的回调 ProcessMessagesAsync 并不是唯一涉及的事情。在您提供的代码示例中,您将并发设置为 1。如果配置了预取(队列在每次请求一条或多条消息时都会获取多条消息),则服务器上的锁定持续时间时钟开始计时对于所有这些消息。因此,如果您的处理稍微低于 MaxLockDuration ,但对于相同的示例,最后一个预取的消息等待处理的时间太长,即使它是在小于锁定持续时间的时间内完成的,它也可能会丢失其锁定,并且在尝试完成该消息时将引发异常。

这就是MaxAutoRenewDuration发挥作用的地方。它的作用是延长与代理的消息租约,为当前正在处理消息的竞争消费者“重新锁定”它。 MaxAutoRenewDuration 应设置为“租约所需的可能最大处理时间”。在您的示例中,它设置为 TimeSpan.FromSeconds(10) 这是非常低的。它需要设置为至少长于 MaxLockDuration 并调整为 ProccesMessage 需要运行的最长时间。考虑预取。

为了帮助可视化它,请考虑客户端有一个内存队列,当您在处理程序中对消息进行逐一串行处理时,可以在其中存储消息。租约在消息从代理到达内存队列时开始。如果内存队列中的总时间加上处理时间超过锁定持续时间,则租约将丢失。您的选择是:

  1. 通过设置 MaxConcurrentCalls > 1 启用并发处理
  2. 增加MaxLockDuration
  3. 减少消息预取(如果使用的话)
  4. 配置 MaxAutoRenewDuration 以续订锁定并克服 MaxLockDuration 约束

注意#4 - 这不是一个有保证的操作。因此,对代理的调用有可能会失败并且消息锁定不会延长。我建议将您的解决方案设计为在锁定持续时间限制内工作。或者,保留消息信息,以便您的处理不必受到消息传递的限制。

关于c# - "MaxAutoRenewDuration"在azure服务总线中的作用是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60377595/

相关文章:

asp.net-mvc-3 - Azure 发布问题 - 忙碌 - 正在重新启动 - 忙碌 - 循环

Azure 时序见解 Gen2 冷存储缺失数据

c# - asp.net web api 无法使用非管理员用户连接到 Azure SQL 数据库

c# - .Net Core TFS 2017 构建在 appsettings.json 文件中丢失了一些应用程序设置

c# - 在哪里设置 PublishReadyToRun?

c# - 将 C++ 例程转换为 C#,主要是指针

c# - 如何在 C# 中使用 struct 和 union

c# - 如何增加处理HTTP请求的数量?

C#动态关键字异常处理

.NET Core 2.1 - 如何创建COM对象并生成*.tlb文件