Служба очереди служебной шины Azure BrokeredMessage выдает "SessionLockLostException" в "RenewLock ()"
Я использую 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 ответ
Ваша очередь требует сеанса и использует разделенную сущность. SessionLockLostException
произойдет рано или поздно, и вы должны повторить получение и обработку. Сообщение будет получено снова и будет обработано потребителем или другим экземпляром, если вы уменьшите масштаб.
Дополнительно
- Вы могли бы изменить
MaxLockDuration
до 5 минут и уменьшите частоту таймера для выдачи обновления блокировки. - Рассмотрите OnMessage API с автоматическим обновлением, чтобы упростить обновление блокировки в вашем коде и обработку исключений. Этот образец может помочь.