我在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 Function App Azure Service Bus trigger triggers twice
请对此提供帮助。
答案 0 :(得分:0)
一些要检查的东西。 All references are to the documentation。
每次都确保它是同一封邮件,并且通过注销邮件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}");
}
如果您的函数引发任何异常,则消息将被重试,但事实并非如此。
最后,最有可能的是,如果您有两个功能应用程序或部署,并且它们被指向相同的队列,那么它们可能会相互竞争,下面复制消息的处理方式。您可能正在获得比赛条件。确保仅运行一个实例,并且队列中没有其他代码竞争。
PeekLock行为。Functions运行时会在PeekLock模式下收到一条消息。如果该函数调用消息完成 成功完成,或者在函数失败时调用Abandon。如果 函数的运行时间超过了PeekLock超时时间,该锁定为 只要该功能正在运行,它就会自动更新。
maxAutoRenewDuration可在host.json中配置,该映射到 OnMessageOptions.MaxAutoRenewDuration。允许的最大数量 根据服务总线文档,设置为5分钟, 而您可以将功能时间限制从默认值 5分钟到10分钟。对于服务总线功能,您不需要 这样做是因为您超出了服务总线的续订限制。
答案 1 :(得分:0)
如果您的 "autoComplete": false
文件中有 host.json
,则消息将被处理,但不会从主题订阅中自动消失。就像在这个 host.json
文件中一样:
{
"version": "2.0",
"extensions": {
"serviceBus": {
"messageHandlerOptions": {
"autoComplete": false
}
}
}
}
删除 autoComplete
或将其设置为 true
应该会使该函数从主题订阅中删除成功处理的消息。
如果你需要更多的控制并且不能使用自动完成功能,那么你可以通过添加一个MessageReceiver
参数来显式地完成消息,并像这样为CompleteAsync
对象调用Message
:
[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());
}