【问题标题】:Azure Service Bus sporadic MessageLockLostExceptionAzure 服务总线零星 MessageLockLostException
【发布时间】:2020-03-29 12:06:04
【问题描述】:

每隔一段时间(千分之一的消息)我在尝试完成消息时收到 MessageLockLostException。

我定义了一个队列,锁定持续时间设置为 30 秒:

在代码中,我使用以下选项创建了一个侦听器:

        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 秒的锁定持续时间内。

最后一条日志行表明消息在 10:31:30 30 秒后重试,这告诉我锁应该在 10:31:05 有效。

会不会是message.SystemProperties.LockToken中包含的锁被破坏了? 另外,这可能是由于短暂的网络中断造成的吗?我想 LockToken 在这种情况下仍然有效。

此应用程序使用 Microsoft.Azure.ServiceBus 4.1.2 在 .net core 3.1 中编写

提前感谢您的帮助!

【问题讨论】:

    标签: azure azureservicebus


    【解决方案1】:

    锁定令牌未损坏。如果是,则整个消息将无效。问题在于消息可能是由预取引起的。检查是否定义了预取,如果是,则降低其值。锁定租用计时器从客户端收到消息的那一刻开始计时。通过预取,客户端在计时器运行时将消息保持在“等待”状态。当消息到达处理回调时,到它完成时,即使更新了锁,锁的持续时间也可能已经到了。

    另一个验证选项是时钟偏差。

    此外,锁更新不是保证操作。这是一个可能会失败的客户端操作。如果您知道您的处理最多可能需要 3 分钟,那么为该值设置锁定持续时间会更好。

    【讨论】:

    • 您好肖恩,感谢您的回复。我没有启用预取。此外,第一次处理尝试的日志中的时间戳似乎没有显示任何延迟(消息在 30 秒后重试)我不使用锁更新,因为它没有必要。在消息完成尝试时,锁似乎仍然有效。(没有其他工作人员拿起消息)
    • 如果我所描述的一切都不是这种情况并且其他消费者不接受,您是否尝试过使用不同的实体?
    • 我不完全确定您对不同实体的含义。你能再解释一下吗?
    • 不同的队列。排除它是一个特定的实体问题。另外,我会尝试 Azure 支持。这感觉很奇怪。如果您有复制品,也许可以分享一个链接。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-09
    相关资源
    最近更新 更多