Azure 函数服务总线触发器运行多次



我在Visual Studio解决方案中添加了一个项目,这是一个服务总线主题触发器函数。我正在使用默认代码运行应用程序,但遇到问题。每当我将消息添加到服务总线主题时,我的触发器每条消息执行 5-6 次,最后出现以下错误。

错误

提供的锁无效。锁定已过期,或者邮件已从队列中删除。

我的代码:

[FunctionName("TopicFunction1")]
public static void Run(
[ServiceBusTrigger("myservicebustopicname", "subscriptionname", Connection = "ServiceBus_NS_ConnectionString")]string message,
Int32 deliveryCount,
ILogger log)
{
log.LogInformation($"ServiceBus topic trigger function processed message: {message}");
}

交货数量达到5-6。

我检查了与此问题相关的多个问题,但它们没有帮助。下面是一个例子。 Azure 函数应用 Azure 服务总线触发器触发器两次

请帮忙。

需要检查的一些事项。所有引用均指向文档。

通过注销消息 ID,确保每次都是相同的消息,并且您不会收到多个消息。

[FunctionName("ServiceBusQueueTriggerCSharp")]                    
public static void Run(
[ServiceBusTrigger("myqueue", Connection = "ServiceBusConnection")] 
string myQueueItem,
Int32 deliveryCount,
DateTime enqueuedTimeUtc,
string messageId,
ILogger log)
{
log.LogInformation($"C# ServiceBus queue trigger function processed message: {myQueueItem}");
log.LogInformation($"EnqueuedTimeUtc={enqueuedTimeUtc}");
log.LogInformation($"DeliveryCount={deliveryCount}");
log.LogInformation($"MessageId={messageId}");
}

如果您的函数抛出任何异常,消息将重试,但情况似乎并非如此。

最后,也是最有可能的是,如果你有两个函数应用或部署,并且它们指向同一个队列,则它们可能相互竞争,下面是消息的处理方式。您可能会遇到竞争条件。确保您只有一个实例正在运行,并且没有其他代码在队列中竞争。

视锁定行为函数运行时在速览锁定模式下接收一条消息。如果函数对消息调用 Complete,则函数 成功完成,或者在函数失败时调用 Abandon 。如果 函数运行时间超过速览锁定超时,锁是 只要函数正在运行,就会自动续订。

maxAutoRenewDuration 可在 host.json 中配置,映射到 OnMessageOptions.MaxAutoRenewDuration。允许的最大值 根据服务总线文档,设置为 5 分钟, 而您可以将函数时间限制从默认值 5分钟到10分钟。对于不需要的服务总线函数 然后执行此操作,因为会超出服务总线续订限制。

如果您的host.json文件中有"autoComplete": false,则将处理消息,但不会自动从主题订阅中消失。就像这个host.json文件一样:

{
"version": "2.0",
"extensions": {
"serviceBus": {
"messageHandlerOptions": {
"autoComplete": false
}
}
}
}

删除autoComplete或将其设置为true应该会使函数从主题订阅中删除成功处理的消息。

如果需要更多控制并且无法使用自动完成功能,则可以通过添加MessageReceiver参数显式完成消息,并为Message对象调用CompleteAsync,如下所示:

[FunctionName("TopicFunction1")]
public static async Task Run(
[ServiceBusTrigger("myservicebustopicname", "subscriptionname", Connection = "ServiceBus_NS_ConnectionString")]Message message,
MessageReceiver messageReceiver,
ILogger log)
{
log.LogInformation($"ServiceBus topic trigger function processed message: {message}");
await messageReceiver.CompleteAsync(message.GetLockToken());
}

最新更新