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

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

问题描述

我正在使用 Microsoft.Azure.ServiceBus .(文档)

我遇到了一个例外:

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

借助以下问题:

1 2 3

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

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

我的问题是:

    1. 答案提出了此异常,因为该锁在长时间的过程之前就已过期,但是在我如果我立即将消息标记为已完成(在长期运行之前),那么我不确定为什么从天蓝色更改锁定持续时间会有什么不同吗?当我将其更改回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天全站免登陆