带有服务总线的 Azure 功能:如果处理出现问题,如何将消息保留在队列中?

Azure functions with service bus: How to keep a message in the queue if something goes wrong with its processing?

我是服务总线的新手,无法理解这一点。

基本上我使用的是连接到服务总线队列的 Azure 函数应用程序。假设从服务总线触发了一个触发器,我从队列中收到一条消息,在处理该消息的过程中,我的代码出现了问题。在这种情况下,我如何确保将该消息再次放回队列中?目前它只是消失在空气中,当我在 VS 上重新启动我的函数应用程序时,队列中的下一条消息被获取。

理想情况下,只有当我的所有数据处理完成并且我点击 myMsg.Success() 时,我才希望它从队列中删除。

public static async Task RunAsync([ServiceBusTrigger("xx", "yy", AccessRights.Manage)]BrokeredMessage mySbMsg, TraceWriter log)
{
      try{ // do something with mySbMsg }

      catch{ // put that mySbMsg back in the queue so it doesn't disappear. and throw exception}
}

我正在阅读有关 mySbMsg.Abandon() 的内容,但看起来这会将消息放入死信队列中,我不确定如何访问它?如果有更好的错误处理方法?

如果您希望消息保留在队列中以供重试,该函数不应吞噬异常,而应抛出异常。这样 Function 就不会自动完成消息并重试。

请记住,这将导致重试消息,如果异常持续存在,最终会将消息移入死信队列。

云队列与内存中的队列有点不同,因为它们需要对客户端在收到队列消息后但在完成消息处理之前崩溃的可能性具有鲁棒性。

收到队列消息后,消息变为"invisible",其他客户端无法接收。这使客户端有机会处理它,并且客户端必须在完成后将其标记为已完成(当您从函数 return 时,Azure Functions 会自动执行此操作)。这样,如果客户端在处理消息的过程中崩溃(我们在云中,因此对由于断电等导致的随机机器崩溃具有鲁棒性),服务器将看到没有完成的消息,假设客户端崩溃,最终重新发送消息。

实际上,这意味着如果您收到队列消息并抛出异常(因此我们不会将消息标记为已完成),它会在几分钟内不可见,但随后会显示出来几分钟后再次出现,另一个客户端可以尝试处理它。换句话说,在 Azure 函数中,队列消息在异常后会自动重试,但在两次重试之间,消息会在几分钟内不可见。

根据我的理解,我认为你的目的是如果在处理消息时出错,它需要重试执行而不是吞下它。如果您使用的是 Azure Functions V2.0,请在 host.json

中定义消息处理程序选项
 "extensions": {
        "serviceBus": {
            "prefetchCount": 100,
            "messageHandlerOptions": {
                "autoComplete": false,
                "maxConcurrentCalls": 1
            }
        }
    }

prefetchCount - 获取或设置消息接收者可以同时请求的消息数。

autoComplete - 触发器是否应在处理后自动调用完成,或者函数代码是否将手动调用完成。

重试消息n次(默认为10)后会将消息传输到DLQ。