我的团队正在使用 Azure Functions 处理来自 Azure 服务总线队列的消息。当消息添加到受尊重的队列中时,它们将被触发。
我们注意到消息的传递计数没有按预期增加。这导致日志条目大量涌入——短短 2.5 天内大约有 800 万个 AppException 条目,这是极其昂贵且意想不到的。
这是由队列中只有 1 条消息引起的(谢天谢地,我们只有 1 条消息......)
我怀疑传递计数没有正确增加,导致消息被过度重试而没有达到最大传递计数并且成为死信。这也可能意味着 AbandonMessageAsync 在某些情况下无法按预期运行。
以下是队列配置的详细信息:
锁定时间:1分钟 最大交付数量:10 消息生存时间:3 天
该函数旨在处理PDF生成请求并使用ServiceBusTrigger接收消息。以下是功能代码的简化版本:
[Function(nameof(PDFGenFunction))]
public async Task Run(
[ServiceBusTrigger(SourceQueue, Connection = ConnectionStringKey)]
ServiceBusReceivedMessage message,
ServiceBusMessageActions messageActions)
{
try
{
_logger.LogInformation($"Message ID: {message.MessageId}");
_logger.LogInformation($"PdfGenerationRequest - Received message: {message.Body.ToString()}");
_logger.LogInformation($"Message Content-Type: {message.ContentType}");
var outputJSON = JsonConvert.DeserializeObject<OutputJSON>(message.Body.ToString());
if (outputJSON != null)
{
var result = await SendPdfGenerationRequest(message.Body.ToString());
if(result.Status == PdfResponseStatus.Queued)
{
await SendMessageToPdfCompletionQueue(result);
await messageActions.CompleteMessageAsync(message);
}
else
{
_logger.LogError($"PdfGenerationRequest - request failed: {result.Urn}, application string: {message.Body.ToString()}");
await messageActions.AbandonMessageAsync(message);
}
}
else
{
_logger.LogError($"PdfGenerationRequest - Invalid JSON string data, application string: {message.Body.ToString()}");
await messageActions.CompleteMessageAsync(message);
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Error processing application submission: {messageBody}", message.Body.ToString());
await messageActions.AbandonMessageAsync(message);
}
}
主机.json
{
"version": "2.0",
"logging": {
"applicationInsights": {
"samplingSettings": {
"isEnabled": true,
"excludedTypes": "Request"
},
"enableLiveMetricsFilters": true
}
},
"extensions": {
"queues": {
"visibilityTimeout": "00:03:00",
"maxDequeueCount": 5
}
}
}
我查看了我们的设置,没有发现实现有任何问题,我唯一能想到的是 API 调用花费了超过 1 分钟的时间,但是这并没有加起来,因为我们有超过 8 分钟百万条记录,周末没有那么多分钟。
返回文档后,以下行是罪魁祸首:
await messageActions.AbandonMessageAsync(message);
此代码会立即解除消息的锁定,从而允许再次触发消息。代码应该做的是 throw;