在 Azure 服务总线队列上重新提交消息时 Messagelock 令牌过期

Messagelock token expired when resubmitting message on Azure Service Bus queue

我有一个包含以下简单代码的 Azure 函数:

       public class MyDequeuer
        {
            [FunctionName("SampleMessageExecutor")]
            public static async Task Run(
                    [ServiceBusTrigger("test-queue", AccessRights.Listen, Connection = "ServiceBusConnectionString")]
                    Message inMessage, string locktoken, ILogger log, ExecutionContext ctx)
            { 
               try {
                  some code..
              } catch(Exception e) {
                await inMessage.DeadLetterAsync(locktoken);
              }
            }
}

这很好用。但是,当我稍后说可能 1 小时或 24 小时后转到死信队列并尝试修复并重新提交来自服务总线资源管理器的消息时,我看到很多错误消息 locktoken 已过期。您应该如何处理消息可能以死信结束并可能在数小时或数天后重新处理的情况?

我正在使用函数运行时 dotnet core 3.1。

实际上关于这个问题 github 中有一个问题:How to intentionally deadletter a message in azure functions v2

首先,消息 class 没有 DeadLetterAsync 方法,对于 v2 或更高版本,您应该使用 MessageReceiver 来实现它。

然后是关于锁定令牌,因为服务总线触发功能会自动完成消息,如果您想自己 DeadLetterAsync 会导致异常。需要改host.json,把autoComplete改成flase,可以参考这个host.json setting.

下面是我的代码,抛出异常和DeadLetter。

        [FunctionName("Function1")]
        public static async System.Threading.Tasks.Task RunAsync([ServiceBusTrigger("myqueue",Connection = "ServiceBusConnectionString")]string myQueueItem, MessageReceiver messageReceiver, string lockToken, ILogger log)
        {

                try
                {
                    throw new Exception();
                }
                catch (Exception) { 
                    await messageReceiver.DeadLetterAsync(lockToken);
                    log.LogInformation(myQueueItem+ " is put into deadletter");
                }
        }

这是我的host.json。

{
  "version": "2.0",

  "extensions": {
    "serviceBus": {
      "prefetchCount": 100,
      "messageHandlerOptions": {
        "autoComplete": false,
        "maxConcurrentCalls": 32,
        "maxAutoRenewDuration": "00:55:00"
      },
      "sessionHandlerOptions": {
        "autoComplete": false,
        "messageWaitTimeout": "00:00:30",
        "maxAutoRenewDuration": "00:55:00",
        "maxConcurrentSessions": 16
      }
    }
  }

}