首页 > 解决方案 > 即使锁未过期,在代理消息上获取 MessageLockLost 异常

问题描述

我已经实现了一个服务总线触发器,我的示例代码如下。

   public static async Task Run([ServiceBusTrigger("myqueue", Connection = 
    "myservicebus:cs")]BrokeredMessage myQueueItem, TraceWriter log)
    {
        try
        {   
            if (myQueueItem.LockedUntilUtc <= DateTime.UtcNow)
            {
                log.Info($"Lock expired.");

                return;
            }

            //renew lock if message lock is about to expire.             
            if ((myQueueItem.LockedUntilUtc - DateTime.UtcNow).TotalSeconds <= defaultLock)
            {
                await myQueueItem.RenewLockAsync();

                return true;
            }                

            //Process message logic        

            await myQueueItem.CompleteAsync();           
        }
        catch (MessageLockLostException ex)
        {
            log.Error($"Message Lock lost. Exception: {ex}");

        }
        catch(CustomException ex)
        {
            //forcefully dead letter if custom exception occurs
            await myQueueItem.DeadLetterAsync();
        }           
        catch (Exception ex)
        {
            log.Error($"Error occurred while processing message. Exception: {ex}");

            await myQueueItem.AbandonAsync();
        }
    }

我已将队列上的默认锁定持续时间设置为 5 分钟。即使锁定实际上没有过期,我也会收到少数请求的消息锁定丢失异常。请求处理时间如下:

  1. 服务总线触发器触发时间:UTC 时间 2018 年 5 月 7 日 07:02:14 +00:00
  2. 代理消息中的 LockedUntilUtc:5 月 7 日 07:07:08.0149905 UTC
  3. 消息锁丢失异常发生在:5 月 07 日 07:02:18 +00:00 2018 UTC

任何人都可以帮我找出我的代码有什么问题。谢谢。

标签: azureazure-functionsazureservicebusazure-servicebus-queues

解决方案


您不应在代码中显式调用CompleteAsyncand AbandonAsync。Azure Functions 运行时将根据您的函数执行结果自动调用这些方法(Complete如果未发生异常,Abandon则否则)。

手动更新锁也不应该是必要的,运行时应该为你管理。如果您在消耗计划上运行,则函数执行的最长持续时间是 5 分钟(默认情况下)。

尝试删除所有管道代码并仅留下//Process message logic,看看是否有帮助。


推荐阅读