Azure Service Bus Queue BrokeredMessage在' RenewLock()'上引发“SessionLockLostException”。

时间:2018-01-18 14:22:40

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

我使用Azure Service Bus Queue接收消息并开始一个长时间运行的活动,可以持续几分钟到几个小时。在活动期间,单独的线程每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)

1 个答案:

答案 0 :(得分:0)

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

此外

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