Azure Сервисная шина sporadi c MessageLockLostException - PullRequest
0 голосов
/ 29 марта 2020

Время от времени (1 на тысячи сообщений) я получаю исключение MessageLockLostException при попытке завершить сообщение.

У меня определена очередь с продолжительностью блокировки, равной 30 с:

enter image description here

В коде я создаю прослушиватель со следующими параметрами:

        var messageHandlerOptions = new MessageHandlerOptions(exceptionReceivedHandler)
        {
            MaxConcurrentCalls = 10,
            AutoComplete = false,
            MaxAutoRenewDuration = TimeSpan.FromSeconds(180)
        };

        var queueClient = ResolveQueueClientByQueueConfigName(queueConfigName);

        _logger.Info($"Listening on queue {queueClient.ServiceBusConnection.Endpoint}{queueClient.QueueName}");
        queueClient.RegisterMessageHandler(MyMessageHandler, messageHandlerOptions);

И в MyMessageHandler я завершаю сообщение после успешной обработки:

    private static async Task CompleteAsync(IReceiverClient queueClient, string lockToken)
    {
        await queueClient.CompleteAsync(lockToken);
    }

    private async Task MyMessageHandler(Message message, CancellationToken cancellationToken)
    {
        //Processing omitted
        await CompleteAsync(queueClient, message.SystemProperties.LockToken);        
    }

Как я уже сказал, это прекрасно работает для большинства сообщений, но время от времени я получаю следующее:

2020-03-27 10:31:01,004 [64] INFO Received message: MessageId:7da4f7ec-9e27-4951-83f5-7f29d8fc93a8
2020-03-27 10:31:01,005 [64] INFO Entity Framework Core "3.1.0" initialized '"SmsDataContext"' using 
provider '"Microsoft.EntityFrameworkCore.SqlServer"' with options: "None"
2020-03-27 10:31:01,087 [109] INFO Sending message to smssender, CorrelationId: 7da4f7ec-9e27-4951-83f5-7f29d8fc93a8, label: SmsSender
2020-03-27 10:31:05,205 [158] INFO Completing message '7da4f7ec-9e27-4951-83f5-7f29d8fc93a8'
2020-03-27 10:31:05,206 [158] ERROR Message handler encountered an exception 
Microsoft.Azure.ServiceBus.MessageLockLostException: The lock supplied is invalid. Either the lock 
expired, or the message has already been removed from the queue, or was received by a different 
receiver instance.
at Microsoft.Azure.ServiceBus.Core.MessageReceiver.DisposeMessagesAsync(IEnumerable`1 lockTokens, 
Outcome outcome)
at Microsoft.Azure.ServiceBus.RetryPolicy.RunOperation(Func`1 operation, TimeSpan operationTimeout)
at Microsoft.Azure.ServiceBus.RetryPolicy.RunOperation(Func`1 operation, TimeSpan operationTimeout)
at Microsoft.Azure.ServiceBus.Core.MessageReceiver.CompleteAsync(IEnumerable`1 lockTokens)
at Bcp.AzureServiceBusHelper.ServiceBusClientHelper.CompleteAsync(String queueName, Message message)
at Bcp.Sms.Validator.ServiceHost.HostedService.ProcessMessagesAsync(Message validatorMessage, 
CancellationToken token) in ***
at Microsoft.Azure.ServiceBus.MessageReceivePump.MessageDispatchTask(Message message). Context: 
Endpoint= prdhybrid.servicebus.windows.net; Entity Path: smsrequestvalidation; Executing Action: 
UserCallback
2020-03-27 10:31:30,949 [109] INFO Received message: MessageId:7da4f7ec-9e27-4951-83f5-7f29d8fc93a8

Так что в этом случае блокировка была взята в 10:31 : 01, и сообщение завершилось неудачно через 4 секунды в 10:31:05, в течение 30 секунд.

Последняя строка журнала указывает, что сообщение было повторено через 30 секунд в 10:31:30, что говорит мне, что блокировка должна была быть действительной в 10: 31: 05.

Возможно ли, что блокировка, содержащаяся в message.SystemProperties.LockToken, повреждена? Кроме того, это может быть из-за короткого прерывания сети? Я полагаю, что LockToken остается действительным в этом случае.

Это приложение написано на. net ядре 3.1 с использованием Microsoft. Azure .ServiceBus 4.1.2

Заранее спасибо за помощь!

1 Ответ

0 голосов
/ 29 марта 2020

Токен блокировки не был поврежден. Если бы это было так, сообщение в целом было бы недействительным. Проблема с сообщением может быть вызвана предварительной загрузкой. Проверьте, определена ли предварительная выборка, и, если да, уменьшите ее значение. Таймер аренды блокировки начинает отсчитываться с того момента, как клиент получает сообщение. С предварительной загрузкой клиент держит сообщение в состоянии ожидания, пока работает таймер. Когда сообщение попадает в обратный вызов обработки, к тому времени, когда оно выполнено, длительность блокировки могла бы увеличиться даже при обновлении блокировки.

Еще одна опция для проверки - это наклон часов.

Кроме того, блокировка продление не гарантированная операция. Это операция на стороне клиента, которая может потерпеть неудачу. Если вы знаете, что ваша обработка может занять до 3 минут, лучше использовать длительность блокировки для этого значения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...