“MaxAutoRenewDuration"的作用是什么?在蔚蓝的服务巴士? [英] What is the role of "MaxAutoRenewDuration" in azure service bus?
问题描述
我正在使用 Microsoft.Azure.ServiceBus
.(doc)>
我得到了一个例外:
<块引用>提供的锁无效.锁已过期,或消息已从队列中删除.
借助这些问题:
我可以通过将 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);//一些长时间运行的进程}
我的问题是:
- 这个 answer 表明引发异常是因为锁在长时间进程之前过期,但在我的如果我立即将消息标记为完成(在长期运行过程之前),所以我不确定为什么从 azure 更改锁定持续时间会有什么不同?当我将它改回 30 秒时,我可以再次看到异常.
- 不确定它是否与问题有关,但目的是什么
MaxAutoRenewDuration
,官方文档是锁自动更新的最大持续时间.
.如果在我的情况下我只有一个应用程序接收器从这个队列中排队,那么它是否不需要,因为我不需要锁定来自另一个应用程序的消息来捕获它?为什么这个值应该大于最长消息锁定持续时间?
- 不确定它是否与问题有关,但目的是什么
您需要考虑一些事项.
- 锁定持续时间
- 从代理获取消息后的总时间
锁定持续时间很简单 - 单个竞争消费者可以租用一条消息多长时间,而无需将该消息租给任何其他竞争消费者.
总时间有点诡异.您注册的用于接收消息的回调 ProcessMessagesAsync
并不是唯一涉及的事情.在您提供的代码示例中,您将并发设置为 1.如果配置了预取(每次请求一条或多条消息时,队列都会收到多个消息),服务器上的锁定持续时间时钟开始滴答作响对于所有这些消息.因此,如果您的处理在 MaxLockDuration
下稍微完成,但对于相同的示例,最后一个预取消息等待处理的时间太长,即使它在小于锁定持续时间的时间内完成,它也可能会丢失其锁定,并在尝试完成该消息时抛出异常.
这是MaxAutoRenewDuration
进入游戏的地方.它所做的是扩展与代理的消息租用,为当前正在处理消息的竞争消费者重新锁定"它.MaxAutoRenewDuration
应设置为可能需要租约的最大处理时间".在您的示例中,它设置为极低的 TimeSpan.FromSeconds(10)
.它需要设置为至少长于 MaxLockDuration
并调整为 ProccesMessage
需要运行的最长时间.考虑到预取.
为了帮助形象化,可以想象客户端有一个内存队列,当您在处理程序中逐个执行消息的串行处理时,可以在其中存储消息.当消息从代理到达内存队列时,租用就开始了.如果内存队列中的总时间加上处理时间超过锁定持续时间,则租约丢失.您的选择是:
- 通过设置
MaxConcurrentCalls
> 1 启用并发处理 - 增加
MaxLockDuration
- 减少消息预取(如果您使用它)
- 配置
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:
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:
- 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.
- Not sure if it related to the question but what is the purpose
MaxAutoRenewDuration
, the official docs isThe 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?
- Not sure if it related to the question but what is the purpose
There are a few things you need to consider.
- Lock duration
- 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:
- Enable concurrent processing by setting
MaxConcurrentCalls
> 1 - Increase
MaxLockDuration
- Reduce message prefetch (if you use it)
- Configure
MaxAutoRenewDuration
to renew the lock and overcome theMaxLockDuration
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屋!