Azure 函数针对同一服务总线队列消息多次运行

Yas*_*sir 1 c# singleton azure azureservicebus azure-functions

我有一个 Azure 函数(基于新的 C# 函数而不是旧的 .csx 函数),每当消息进入 Azure 服务总线队列时就会触发该函数。一旦该函数被触发,它就开始处理服务总线消息。它对消息进行解码、读取大量数据库、更新大量其他数据库等等……这有时可能需要 30 分钟以上。

由于这不是一个时间敏感的过程,30 分钟甚至 60 分钟都不是问题。问题是,与此同时,Azure Function 似乎再次启动并一次又一次地获取相同的消息并重新处理它。这是一个问题,会导致我们的业务逻辑出现问题。

那么,问题来了,我们能否强制Azure函数以单例模式运行呢?或者如果这是不可能的,我们如何更改轮询间隔?

Sea*_*man 6

AutoRenewTimeout并不像建议的那么好。它有一个您需要注意的缺点。这不是一个有保证的操作。作为客户端发起的操作,它可能而且有时失败,使您处于与今天相同的状态。

解决这个问题你可以做的就是检查你的设计。如果您有一个长时间运行的进程,那么您将处理该消息,并将处理交给运行时间长于 的进程MaxLockDuration。您的函数花费如此长的时间这一事实表明您有一个长时间运行的进程。消息传递不是为此而设计的。

潜在的解决方案之一是获取消息,在存储表中注册处理意图。让另一个存储表触发函数来启动可能需要 X 分钟的处理。将其标记为单例。通过这样做,您将并行处理消息,将“长时间运行处理的请求”写入存储表,完成服务总线消息传递,因此不会触发其重新处理。通过长时间运行的处理,您可以决定如何处理故障情况。

希望有帮助。


And*_*NET 5

该问题与服务总线设置有关...

发生的情况是,消息被添加到队列中,然后将消息传递给函数,并对该消息放置锁,以便在您锁定该消息时,其他消费者无法查看/处理该消息。

如果在该锁定期内,您没有告诉服务总线您已处理该文件,或者没有延长锁定,则锁定将从消息中删除,并且它将对随后处理该消息的其他服务可见,这就是你正在看到。

幸运的是,Azure Functions 可以自动为你续订锁定。该host.json文件中有一个autoRenewTimeout设置,指定您希望 Azure Functions 继续更新锁定的时间。

https://github.com/Azure/azure-webjobs-sdk-script/wiki/host.json

"serviceBus": {
  // the maximum duration within which the message lock will be renewed automatically.
  "autoRenewTimeout": "00:05:00"
},
Run Code Online (Sandbox Code Playgroud)