[英]Azure Function App Service Bus Topic trigger random error while settings some PrefetchCount limit and lock error as well
Below code I have for one of the Azure Function Service Bus topic trigger, where I am receiving the service bus messages in batch and each message I am putting into one Task.下面的代码用于 Azure Function 服务总线主题触发器之一,我在其中批量接收服务总线消息,并且每条消息都放入一个任务中。
I have below service bus settings as well,我也有以下服务总线设置,
"serviceBus": {
"prefetchCount": 0,
"messageHandlerOptions": {
"autoComplete": false,
"maxConcurrentCalls": 32,
"maxAutoRenewDuration": "00:05:00"
}
}
Things working as expected, but 2 issues I am seeing randomly,事情按预期工作,但我随机看到 2 个问题,
WRN] Prefetch count for receiver with Identifier ingestion-topic/Subscriptions/ingestion-sub-80c010ae-2078-4bdf-b7e2-c51672e668d6 is less than the max messages requested.
WRN] 标识符为 ingestion-topic/Subscriptions/ingestion-sub-80c010ae-2078-4bdf-b7e2-c51672e668d6 的接收方的预取计数小于请求的最大消息数。 When using prefetch, it isn't possible to receive more than the prefetch count in any single Receive call: PrefetchCount: 10;
使用预取时,在任何单个 Receive 调用中都不能接收超过预取计数: PrefetchCount: 10; MaxMessages: 1000
最大消息数:1000
Question - What this mean?问题 - 这是什么意思? and what's the perfect settings above different settings?
什么是不同设置之上的完美设置?
function: RunAsync The lock supplied is invalid.
function:RunAsync 提供的锁无效。 Either the lock expired, or the message has already been removed from the queue
锁已过期,或者消息已从队列中删除
Thanks and appreciate感谢和赞赏
[FunctionName(nameof(RunAsync))]
public async Task RunAsync([ServiceBusTrigger("%InputTopic%", "%InputSubscription%", Connection = "ServiceBusConnection", AutoCompleteMessages = false)]
ServiceBusReceivedMessage[] messages, ServiceBusMessageActions messageActions)
{
_logger.LogInformation($"Number of orders: {messages.Length}");
var taskList = new List<Task<Tuple<bool, ServiceBusReceivedMessage>>>();
foreach (var message in messages)
{
try
{
var order = message.Body.ToObjectFromJson<Order>();
//process each messages in parallel with dedicated task
taskList.Add(Task.Run(() => _messageProcessor.Process(order.ArticleNumber, message)));
//If the code execution makes it here, then you are good to go
await messageActions.CompleteMessageAsync(message);
}
catch (TimeoutException toex)
{
//Wait a couple of seconds
//Let's assume the retry fails again, so we want abandon it
//This will put the message back into the queue and increment DeliveryCount by 1
_logger.LogInformation($"A transient exception happened: {toex.Message}");
await messageActions.AbandonMessageAsync(message);
}
catch (FormatException fex)
{
if (message.DeliveryCount > 10)
{
_logger.LogInformation($"Sending message; {message.MessageId} to DLQ");
await messageActions.DeadLetterMessageAsync(message, fex.Message + " sending to DLQ");
}
else
{
_logger.LogInformation($"An format exception happened: {fex.Message}, DeliveryCount: {message.DeliveryCount}");
await messageActions.AbandonMessageAsync(message);
}
}
catch (Exception ex)
{
_logger.LogInformation($"An exception happened: {ex.Message}");
//Comment out this CompleteAsync and the message will get processed when Lock Duration is breached
await messageActions.CompleteMessageAsync(message);
}
}
//get responses for all the task
var responses = await Task.WhenAll(taskList);
//make decision to complete or DeadLetter
foreach (var (flag, message) in responses)
{
switch (flag)
{
case false:
_logger.LogError("Error processing message");
break;
default:
var order = message.Body.ToObjectFromJson<Order>();
_logger.LogInformation($"OrderID: {order.Id}, ArticleNumber: {order.ArticleNumber}, Amount: {order.Amount}, Customer First Name: {order.Customer.FirstName}, Customer Last Name: {order.Customer.LastName}");
break;
}
}
}
you can set PrefetchCount
to 0 it is and optional parameter.您可以将
PrefetchCount
设置为 0 它是可选参数。 It is available if you want high speed and want message to be ready after the maximum number of messages are already fetch.如果您想要高速并希望在已获取最大数量的消息后准备好消息,则可以使用它。
That is why you are getting the warning because it seems that the number of messages available is less that the max count and you are setting up the prefetch count on top of it.这就是您收到警告的原因,因为似乎可用消息的数量少于最大数量,并且您正在其之上设置预取计数。
Regarding the error try to setup retry policy so that every time something fails the function will try to retry the task again.关于错误尝试设置重试策略,以便每次失败时 function 将尝试再次重试任务。 This is done by setting up a parameter called
maximum retry coun
t.这是通过设置一个称为
maximum retry coun
的参数来完成的。
Reference:参考:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.