Azure 关于MessageOptions.AutoRenewTimeout的指南

Azure 关于MessageOptions.AutoRenewTimeout的指南,azure,azureservicebus,azure-servicebus-queues,Azure,Azureservicebus,Azure Servicebus Queues,有人能提供更多关于Azure服务总线OnMessageOptions.AutoRenewTimeout使用的指导吗 因为我还没有找到很多关于这个选项的文档,我想知道这是否是更新消息锁的正确方法 我的用例: 1) 消息处理队列的锁定持续时间为5分钟(允许的最大值) 2) 消息处理器使用OnMessageAsync消息泵从队列中读取消息(使用ReceiveMode.PeekLock),在手动调用msg.CompleteAsync之前,长时间运行的处理可能需要10分钟来处理消息 3) 我希望消息处理

有人能提供更多关于Azure服务总线OnMessageOptions.AutoRenewTimeout使用的指导吗

因为我还没有找到很多关于这个选项的文档,我想知道这是否是更新消息锁的正确方法

我的用例:

1) 消息处理队列的锁定持续时间为5分钟(允许的最大值)

2) 消息处理器使用OnMessageAsync消息泵从队列中读取消息(使用ReceiveMode.PeekLock),在手动调用msg.CompleteAsync之前,长时间运行的处理可能需要10分钟来处理消息

3) 我希望消息处理器自动更新其锁定,直到预期完成处理(约10分钟)。如果在这段时间后仍未完成,锁应自动释放

谢谢

--更新

我从来没有得到过更多关于自动恢复时间的指导。最后,我使用了一个自定义MessageLock类,该类根据计时器自动更新消息锁

见要点-
我的员工也有同样的问题。即使消息已成功处理,但由于处理时间较长,service bus会移除应用于它的锁,消息也可再次接收。其他可用工作进程接收此消息并再次开始处理它。如果我错了,请纠正我,但在您的情况下,OnMessageAsync将使用同一消息多次调用,并且您将同时处理多个任务。在流程结束时,将引发MessageLockLost异常,因为该消息未应用锁。 我用下面的代码解决了这个问题

\u requestQueueClient.OnMessage(
请求消息=>
{
RenewMessageLock(请求消息);
var messageLockTimer=newsystem.Timers.Timer(TimeSpan.FromSeconds(290));
messageLockTimer.Appeased+=(源代码,e)=>
{
RenewMessageLock(请求消息);
};
messageLockTimer.AutoReset=false;//by deffault为true
messageLockTimer.Start();
/*-----处理请求消息------*/
requestMessage.Complete();
messageLockTimer.Stop();
}
private void RenewMessageLock(BrokeredMessage requestMessage)
{
尝试
{
requestMessage.RenewLock();
}
捕获(异常)
{
}
}

您的帖子发布后有一些挂载,可能您已经解决了这个问题,所以您可以分享您的解决方案。

要处理长消息处理,您应该设置
AutoRenewTimeout
==10分钟(在您的情况下)。这意味着每次
LockDuration
过期时,锁都将在这10分钟内更新


因此,例如,如果您的
LockDuration
为3分钟,而
AutoRenewTimeout
为10分钟,则每3分钟锁将自动更新一次(3分钟、6分钟和9分钟后)自消息被使用后,锁将在12分钟后自动释放。

根据我个人的偏好,OnMessageOptions.AutoRenewTimeout对于租约续订选项来说有点太粗糙了。如果将其设置为10分钟,并且出于任何原因,消息是。Complete()仅在10分5秒后,消息将再次显示在消息队列中,并将被下一个备用工作进程消耗,整个处理过程将再次执行。这是浪费,而且还使工作进程无法执行其他未处理的请求

要解决此问题,请执行以下操作:

  • 更改工作进程以验证它刚从消息队列收到的项目是否尚未处理。查找存储在某处的成功/失败结果。如果已处理,请调用BrokeredMessage.Complete()并继续等待下一个项目弹出

  • 定期调用BrokeredMessage.RenewalLock()——在锁过期之前,如每10秒一次——并将OnMessageOptions.AutoRenewTimeout设置为TimeSpan.Zero。因此,如果处理项目的工作进程崩溃,消息将更快地返回到消息队列,并由下一个备用工作进程拾取


  • 这是一个非常有用的解释。我在其他任何地方都找不到它。谢谢!@A.Kostadinov有一个很好的解决方案,可以定期调用RenewLock(),请封装在一些QueueListener类中,这样计时器代码就不会在整个代码库中重复。