Azure Http 触发功能应用仅在停止并再次启动时有效

Azure Http trigger function app works only when stop and restart again

我使用了Http trigger function app,想从service bus topic读取消息。

安装 nuget - Microsoft.Azure.ServiceBus.

但是当我触发Http函数消息为空时,它第二次只读取一次消息。

当我停止并重新启动函数应用程序并触发它时,由于第二次触发消息为空,它第一次再次正常工作。

为什么会有这样的行为?

  [FunctionName("Test")]
        public static async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
            ILogger log)
        {

            string serviceBusConnectionString = Environment.GetEnvironmentVariable("ConnectionStringSettingName");
            var messageReceiver = new MessageReceiver(serviceBusConnectionString, Environment.GetEnvironmentVariable("EntityPath"), ReceiveMode.PeekLock);

            var messages = await messageReceiver.ReceiveAsync(500, TimeSpan.FromSeconds(1));

            if (messages != null)
            {
            foreach (Message item in messages)
                    {
           // process messages and complete it.
   await messageReceiver.CompleteAsync(item.SystemProperties.LockToken);

我想使用 Http Trigger 只是因为我必须从其他地方调用此 http 函数,所以不能使用服务总线触发器。目前只有一个地方我调用了功能应用程序,所以 ReceiveAsync 应该可以工作

我认为需要像下面那样使用 ReceiveAsyncReceiveAndDelete -

var messages = await messageReceiver.ReceiveAsync(500);

var messageReceiver = new MessageReceiver(serviceBusConnectionString, Environment.GetEnvironmentVariable("EntityPath"), ReceiveMode.ReceiveAndDelete);

您需要使用 PeekAsync 而不是 ReceiveAsync。

Peek 会将消息保留在队列中,以便它们可以由另一个进程处理,其中 as receive 将它们标记为正在处理以防止多次传递。重新启动您的函数应用程序将回滚将消息放回队列的接收。

https://docs.microsoft.com/en-us/dotnet/api/microsoft.azure.servicebus.core.messagereceiver.peekasync?view=azure-dotnet#Microsoft_Azure_ServiceBus_Core_MessageReceiver_PeekAsync

使用一条消息时,您只能阅读一次,因此您看到的是服务总线的预期行为。

我建议您考虑重组您的解决方案以解决这个问题。

很难提供具体的解决方案,因为我不知道您的全部要求,但我建议将此 azure 函数更改为服务总线触发函数,并让它在逻辑应用程序可以查询的地方写出数据轻松如存储帐户

第二个选项是完全放弃该函数并直接在您的逻辑应用程序中使用服务总线触发器。这被配置为每隔一段时间轮询服务总线,并且将 运行 重复,直到在等待轮询间隔之前处理完所有消息。