Sha*_*ani 9 c# azure azureservicebus .net-core
我正在使用Microsoft.Azure.ServiceBus. (文档)
我得到了一个例外:
提供的锁无效。锁已过期,或者消息已从队列中删除。
通过这些问题的帮助:
我可以Exception通过设置AutoCompletetofalse和将 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
}
Run Code Online (Sandbox Code Playgroud)
我的问题是:
MaxAutoRenewDuration,官方文档是The maximum duration during which locks are automatically renewed.. 如果在我的情况下,我只有一个应用程序接收器从这个队列中排队,那么它是否不需要,因为我不需要锁定来自另一个应用程序的消息来捕获它?为什么这个值应该大于最长消息锁定持续时间?Sea*_*man 14
您需要考虑一些事项。
锁定持续时间很简单 - 单个竞争消费者可以租用一条消息多长时间,而无需将该消息租给任何其他竞争消费者。
总时间有点诡异。您ProcessMessagesAsync注册接收消息的回调并不是唯一涉及的事情。在您提供的代码示例中,您将并发性设置为 1。如果配置了预取(每次请求一条或多条消息时,队列都会收到多个消息),则服务器上的锁定持续时间时钟开始滴答作响对于所有这些消息。因此,如果您的处理稍微低于MaxLockDuration但对于相同的示例,最后一个预取消息等待处理的时间过长,即使它在小于锁定持续时间的时间内完成,它也可能失去锁定并抛出异常尝试完成该消息。
这是MaxAutoRenewDuration进入游戏的地方。它所做的是扩展与代理的消息租用,为当前正在处理消息的竞争消费者“重新锁定”它。MaxAutoRenewDuration应设置为“可能需要租约的最大处理时间”。在您的示例中,它设置为TimeSpan.FromSeconds(10)极低。它需要设置为至少长于MaxLockDuration并调整为ProccesMessage需要运行的最长时间。考虑到预取。
为了帮助可视化它,请考虑客户端有一个内存队列,当您在处理程序中逐个执行消息的串行处理时,可以在其中存储消息。当消息从代理到达内存队列时,租用就开始了。如果内存队列中的总时间加上处理时间超过锁定持续时间,则租约丢失。您的选择是:
MaxConcurrentCalls> 1启用并发处理MaxLockDurationMaxAutoRenewDuration更新锁并克服MaxLockDuration约束注意#4 - 这不是一个有保证的操作。因此,对代理的调用可能会失败并且消息锁不会被扩展。我建议将您的解决方案设计为在锁定持续时间限制内工作。或者,保留消息信息,以便您的处理不必受到消息传递的限制。
| 归档时间: |
|
| 查看次数: |
5290 次 |
| 最近记录: |