即使锁定未过期,代理消息也会出现 MessageLockLost 异常

Getting MessageLockLost exception on brokered message even though lock was not expired

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

   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. 服务总线触发器触发时间:5 月 7 日 07:02:14 +00:00 2018 utc
  2. 代理消息中的 LockedUntilUtc:5 月 7 日 07:07:08.0149905 utc
  3. 消息锁丢失异常发生在:May 07 07:02:18 +00:00 2018 utc

谁能帮我找出我的代码到底出了什么问题。 谢谢

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

也不需要手动更新锁,运行时应该会为您管理。如果您 运行 使用消费计划,函数执行的最长持续时间无论如何都是 5 分钟(默认情况下)。

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