“MaxAutoRenewDuration"的作用是什么?在蔚蓝的服务巴士? [英] What is the role of "MaxAutoRenewDuration" in azure service bus?

查看:20
本文介绍了“MaxAutoRenewDuration"的作用是什么?在蔚蓝的服务巴士?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

我得到了一个例外:

<块引用>

提供的锁无效.锁已过期,或消息已从队列中删除.

借助这些问题:

123

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

_queueClient.RegisterMessageHandler(ProcessMessagesAsync, newMessageHandlerOptions(ExceptionReceivedHandler){MaxConcurrentCalls = 1,MaxAutoRenewDuration = TimeSpan.FromSeconds(10),自动完成 = 假});私有异步任务 ProcessMessagesAsync(消息消息,CancellationToken 令牌){等待 ProccesMessage(message);}私有异步任务 ProccesMessage(消息消息){//在长时间处理之前应关闭完成等待 _queueClient.CompleteAsync(message.SystemProperties.LockToken);等待 DoFoo(message.Body);//一些长时间运行的进程}

我的问题是:

    1. 这个 answer 表明引发异常是因为锁在长时间进程之前过期,但在我的如果我立即将消息标记为完成(在长期运行过程之前),所以我不确定为什么从 azure 更改锁定持续时间会有什么不同?当我将它改回 30 秒时,我可以再次看到异常.

    1. 不确定它是否与问题有关,但目的是什么MaxAutoRenewDuration,官方文档是锁自动更新的最大持续时间..如果在我的情况下我只有一个应用程序接收器从这个队列中排队,那么它是否不需要,因为我不需要锁定来自另一个应用程序的消息来捕获它?为什么这个值应该大于最长消息锁定持续时间?

解决方案

您需要考虑一些事项.

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

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

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

这是MaxAutoRenewDuration 进入游戏的地方.它所做的是扩展与代理的消息租用,为当前正在处理消息的竞争消费者重新锁定"它.MaxAutoRenewDuration 应设置为可能需要租约的最大处理时间".在您的示例中,它设置为极低的 TimeSpan.FromSeconds(10).它需要设置为至少长于 MaxLockDuration 并调整为 ProccesMessage 需要运行的最长时间.考虑到预取.

为了帮助形象化,可以想象客户端有一个内存队列,当您在处理程序中逐个执行消息的串行处理时,可以在其中存储消息.当消息从代理到达内存队列时,租用就开始了.如果内存队列中的总时间加上处理时间超过锁定持续时间,则租约丢失.您的选择是:

  1. 通过设置 MaxConcurrentCalls > 1
  2. 启用并发处理
  3. 增加MaxLockDuration
  4. 减少消息预取(如果您使用它)
  5. 配置MaxAutoRenewDuration来更新锁并克服MaxLockDuration约束

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

I'm using Microsoft.Azure.ServiceBus. (doc)

I was getting an exception of:

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

By the help of these questions:

1, 2, 3,

I am able to avoid the Exception by setting the AutoComplete to false and by increment the Azure's queue lock duration to its max (from 30 seconds to 5 minutes).

_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
}

My questions are:

    1. This answer suggested that the exception was raised because the lock was being expired before the long time process, but in my case I was marking the message as complete immediately (before the long run process), so I'm not sure why changing the locking duration from azure made any difference? when I change it back to 30 seconds I can see the exception again.

    1. Not sure if it related to the question but what is the purpose MaxAutoRenewDuration, the official docs is The maximum duration during which locks are automatically renewed.. If in my case I have only one app receiver that en-queue from this queue, so is it not needed because I do not need to lock the message from another app to capture it? and why this value should be greater than the longest message lock duration?

解决方案

There are a few things you need to consider.

  1. Lock duration
  2. Total time since a message acquired from the broker

The lock duration is simple - for how long a single competing consumer can lease a message w/o having that message leased to any other competing consumer.

The total time is a bit tricker. Your callback ProcessMessagesAsync registered with to receive the message is not the only thing that is involved. In the code sample, you've provided, you're setting the concurrency to 1. If there's a prefetch configured (queue gets more than one message with every request for a message or several), the lock duration clock on the server starts ticking for all those messages. So if your processing is done slightly under MaxLockDuration but for the same of example, the last prefetched message was waiting to get processed too long, even if it's done within less than lock duration time, it might lose its lock and the exception will be thrown when attempting completion of that message.

This is where MaxAutoRenewDuration comes into the game. What it does is extends the message lease with the broker, "re-locking" it for the competing consumer that is currently handling the message. MaxAutoRenewDuration should be set to the "possibly maximum processing time a lease will be required". In your sample, it's set to TimeSpan.FromSeconds(10) which is extremely low. It needs to be set to be at least longer than the MaxLockDuration and adjusted to the longest period of time ProccesMessage will need to run. Taking prefetching into consideration.

To help to visualize it, think of the client-side having an in-memory queue where the messages can be stored while you perform the serial processing of the messages one by one in your handler. Lease starts the moment a message arrives from the broker to that in-memory queue. If the total time in the in-memory queue plus the processing exceeds the lock duration, the lease is lost. Your options are:

  1. Enable concurrent processing by setting MaxConcurrentCalls > 1
  2. Increase MaxLockDuration
  3. Reduce message prefetch (if you use it)
  4. Configure MaxAutoRenewDuration to renew the lock and overcome the MaxLockDuration constraint

Note about #4 - it's not a guaranteed operation. Therefore there's a chance a call to the broker will fail and message lock will not be extended. I recommend designing your solutions to work within the lock duration limit. Alternatively, persist message information so that your processing doesn't have to be constrained by the messaging.

这篇关于“MaxAutoRenewDuration"的作用是什么?在蔚蓝的服务巴士?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆