问题描述
我正在尝试使用服务总线队列触发器从队列中消耗一条消息,并完成一些工作,这需要一些时间才能完成。我不希望其他处理器在我处理消息时选择该消息。我在host.json中有以下配置。当我在 await receiver.CompleteAsync(lockToken); 上从队列中收到消息时 我收到一个异常“提供的锁无效。要么锁已过期,要么消息已从队列中删除。”
"serviceBus": {
"prefetchCount": 1,"autoRenewTimeout": "00:05:00","messageHandlerOptions": {
"autoComplete": false,"maxConcurrentCalls": 1,"maxAutoRenewDuration": "00:04:00"
}
}
Azure Function的代码如下
public static void Run([ServiceBusTrigger("testqueue",Connection = "AzureServiceBus.ConnectionString")]Message message,MessageReceiver messageReceiver,ILogger log)
{
log.Loginformation($"C# ServiceBus queue trigger function processed message: {messageReceiver.ClientId}");
log.Loginformation($"Message={Encoding.UTF8.GetString(message.Body)}");
string lockToken = message.SystemProperties.LockToken;
log.Loginformation($"Processing Message:={Encoding.UTF8.GetString(message.Body)}");
DoSomeJob(messageReceiver,lockToken,log);
}
public static async void DoSomeJob(MessageReceiver receiver,string lockToken,ILogger log)
{
try
{
await Task.Delay(360000);
await receiver.CompleteAsync(lockToken);
}
catch (Exception ex)
{
log.Loginformation($"Error In Job={ex}");
}
}
解决方法
在将my @a = (undef,q{},1);
# All of these test whether 'array' has four elements:
print q{array has four elements} if @a == 4;
print q{array has four elements} unless @a != 4;
@a == 4 and print q{array has four elements};
!(@a != 4) and print q{array has four elements};
# All of the above print:
# array has four elements
# All of these test whether array is not empty:
print q{array is not empty} if @a;
print q{array is not empty} unless !@a;
@a and print q{array is not empty};
!(!@a) and print q{array is not empty};
# All of the above print:
# array is not empty
设置为10分钟的情况下配置由Azure Service Bus触发的Azure功能时,您要求触发器将锁定延长长达10分钟。这不是不是的保证操作,因为它是由客户端发起的,并且最长一次锁定时间为5分钟。鉴于此,扩展锁的操作可能会失败,并且锁将被释放,从而导致函数的另一个实例同时进行处理,而原始处理仍在进行。
要查看的另一方面是将maxAutoRenewDuration
设置为100,将prefetchCount
设置为32。这意味着您要提取多达100条消息并进行处理到32那我不知道实际的功能代码是否运行了超过50秒(在您的示例中),但是预取的消息锁不会自动更新。因此,如果在队列的maxConcurrentCalls
时间(默认情况下少于5分钟)内未对预提取的消息进行处理,则其中一些预提取的消息将在丢失后开始处理,可选续订和完成方式锁。
我建议:
- 检查
MaxLockDuration
的长度不要太短以适应您的预取和并发。 - 更新
MaxLockDuration
,以确保您不会超量获取。 - 如果可以在5分钟或更短的时间内完成一次邮件处理,则宁愿选择此方法,也不希望自动续订。