【问题标题】:Azure Service Bus Queue BrokeredMessage throws “SessionLockLostException” on 'RenewLock ()'Azure 服务总线队列 BrokeredMessage 在“RenewLock ()”上引发“SessionLockLostException”
【发布时间】:2018-06-27 15:42:00
【问题描述】:

我使用 Azure 服务总线队列来接收消息并开始一个长时间运行的活动,该活动可能会持续几分钟到几个小时。在活动期间,一个单独的线程每 30 秒更新一次锁,直到活动完成。在 BrokeredMessage.RenewLock() 上,发生异常,下面的完整跟踪:“Microsoft.ServiceBus.Messaging.SessionLockLostException”(这是第一次发生)

这是更新锁的代码

Timer resetToken = new System.Threading.Timer (e => RenewLockQueueJobMessage (), null, TimeSpan.Zero, TimeSpan.FromSeconds (30));
private void RenewLockQueueJobMessage ()
{
   brokeredMessage.RenewLock ();
 }

队列的配置:

QueueDescription queueDescription = new QueueDescription (queueName);
queueDescription.EnablePartitioning = true;
queueDescription.RequiresSession = true;
queueDescription.RequiresDuplicateDetection = true;
queueDescription.EnableDeadLetteringOnMessageExpiration = true;
queueDescription.DefaultMessageTimeToLive = TimeSpan.MaxValue;
queueDescription.LockDuration = TimeSpan.FromMinutes (1);
var manager = NamespaceManager.CreateFromConnectionString (connectionString);
manager.CreateQueue (queueDescription);

异常跟踪:

Microsoft.ServiceBus.Messaging.SessionLockLostException: Channel:uuid:;Link: TrackingId:, SystemTracker:net.tcp:,  ---> System.ServiceModel.FaultException`1[System.ServiceModel.ExceptionDetail]:
   at Microsoft.ServiceBus.Messaging.Sbmp.DuplexRequestBindingElement.DuplexRequestSessionChannel.ThrowIfFaultMessage(Message wcfMessage)
   at Microsoft.ServiceBus.Messaging.Sbmp.DuplexRequestBindingElement.DuplexRequestSessionChannel.HandleMessageReceived(IAsyncResult result)
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at Microsoft.ServiceBus.Common.AsyncResult.End[TAsyncResult](IAsyncResult result)
   at 

    Microsoft.ServiceBus.Messaging.Sbmp.DuplexRequestBindingElement.DuplexRequestSessionChannel.EndRequest(IAsyncResult result)
       at Microsoft.ServiceBus.Messaging.Channels.ReconnectBindingElement.ReconnectChannelFactory`1.RequestSessionChannel.RequestAsyncResult.<>c.<GetAsyncSteps>b__9_3(RequestAsyncResult thisPtr, IAsyncResult r)
       at Microsoft.ServiceBus.Messaging.IteratorAsyncResult`1.StepCallback(IAsyncResult result)
    --- End of stack trace from previous location where exception was thrown ---
       at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
       at Microsoft.ServiceBus.Common.AsyncResult.End[TAsyncResult](IAsyncResult result)
       at Microsoft.ServiceBus.Messaging.Channels.ReconnectBindingElement.ReconnectChannelFactory`1.RequestSessionChannel.EndRequest(IAsyncResult result)
       at Microsoft.ServiceBus.Messaging.Sbmp.RedirectBindingElement.RedirectContainerChannelFactory`1.RedirectContainerSessionChannel.RequestAsyncResult.<>c__DisplayClass8_1.<GetAsyncSteps>b__4(RequestAsyncResult thisPtr, IAsyncResult r)
       at Microsoft.ServiceBus.Messaging.IteratorAsyncResult`1.StepCallback(IAsyncResult result)
    --- End of stack trace from previous location where exception was thrown ---
       at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
       at Microsoft.ServiceBus.Common.AsyncResult.End[TAsyncResult](IAsyncResult result)
       at Microsoft.ServiceBus.Messaging.Sbmp.RedirectBindingElement.RedirectContainerChannelFactory`1.RedirectContainerSessionChannel.EndRequest(IAsyncResult result)
       at Microsoft.ServiceBus.Messaging.Channels.ReconnectBindingElement.ReconnectChannelFactory`1.RequestSessionChannel.RequestAsyncResult.<>c.<GetAsyncSteps>b__9_3(RequestAsyncResult thisPtr, IAsyncResult r)
       at Microsoft.ServiceBus.Messaging.IteratorAsyncResult`1.StepCallback(IAsyncResult result)
    --- End of stack trace from previous location where exception was thrown ---
       at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
       at Microsoft.ServiceBus.Common.AsyncResult.End[TAsyncResult](IAsyncResult result)
       at Microsoft.ServiceBus.Messaging.Channels.ReconnectBindingElement.ReconnectChannelFactory`1.RequestSessionChannel.EndRequest(IAsyncResult result)
       at Microsoft.ServiceBus.Messaging.Sbmp.SbmpMessageReceiver.RenewLockAsyncResult.<>c.<GetAsyncSteps>b__10_1(RenewLockAsyncResult thisPtr, IAsyncResult a)
       at Microsoft.ServiceBus.Messaging.IteratorAsyncResult`1.StepCallback(IAsyncResult result)
    --- End of stack trace from previous location where exception was thrown ---
       at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
       at Microsoft.ServiceBus.Common.AsyncResult.End[TAsyncResult](IAsyncResult result)
       at Microsoft.ServiceBus.Messaging.Sbmp.SbmpMessageReceiver.OnEndRenewMessageLocks(IAsyncResult result)
       --- End of inner exception stack trace ---
       at Microsoft.ServiceBus.Common.ExceptionExtensions.ThrowException(Exception exception)
       at Microsoft.ServiceBus.Common.AsyncResult.End[TAsyncResult](IAsyncResult result)
       at Microsoft.ServiceBus.Messaging.ReceiveContext.EndRenewLock(IAsyncResult result)
       at Microsoft.ServiceBus.Messaging.ReceiveContext.EndRenewLock(IAsyncResult result)

【问题讨论】:

    标签: azure azureservicebus servicebus azure-servicebus-queues brokeredmessage


    【解决方案1】:

    您的队列需要一个会话并使用分区实体。 SessionLockLostException 迟早会发生,您应该重新尝试接收和处理。如果您向外扩展,消息将再次被拾取并由消费者或另一个实例重新处理。

    另外

    1. 您可以将MaxLockDuration 更改为 5 分钟并减少计时器频率以发出锁更新。
    2. 考虑使用具有自动更新功能的 OnMessage API 来简化代码中的锁更新和异常处理。这个sample 可以提供帮助。

    【讨论】:

    • 肖恩,这个异常发生在长时间运行的活动中,我需要在相同的实例和相同的状态下恢复表单异常。再次接收和处理将重新启动活动。异常发生后我能做些什么来恢复活动吗?有什么办法可以防止异常?
    • 如果你的锁丢了,恐怕你无能为力。该消息可供获取,您无法对其执行和处置操作。这就是野兽的本性。如果您需要长时间运行的操作不应该因为锁而失败,您需要求助于处理程序/回调处理。但这听起来像是对您的架构的重大更改。
    猜你喜欢
    • 2015-01-03
    • 1970-01-01
    • 2017-02-25
    • 1970-01-01
    • 1970-01-01
    • 2015-07-18
    • 1970-01-01
    • 1970-01-01
    • 2012-08-28
    相关资源
    最近更新 更多