我有一个HTTP触发Azure函数,可将消息添加到队列中:outputQueue.AddAsync(myMessage);然后触发队列触发Azure功能。它将100条消息添加到同一队列。这100条消息中的每条消息都通过此功能出队并进行处理。此过程大约需要5-7分钟。我的functionTimeout是10分钟。有时(在10%的呼叫中)同一条消息会被出队,并且处理两次甚至更多,以为先前处理此消息是成功的。我还注意到,每次这样的冗余出队都发生在同一次按摩的上次出队后约10分钟(似乎与我的functionTimeout为10分钟有关)。这样看来,完成处理后,该功能并未结束,因此也没有从队列中删除,这导致另一个实例将其出队。
当我查看Application Insights的Failures部分时,我发现大约进行1K操作时,大约有10个WebException和2个TimeoutException。
WebException:
消息:远程服务器返回错误:(409)冲突。 失败的方法: Microsoft.WindowsAzure.Storage.Shared.Protocol.HttpResponseParsers.ProcessExpectedStatusCodeNoExceptiond FormattedMessage:发生未处理的异常。主机正在关闭。
TimeoutException:
消息:客户端无法在指定的超时时间内完成操作。客户端无法在指定的超时时间内完成操作。 失败的方法:Microsoft.WindowsAzure.Storage.Core.Executor.Executor.EndExecuteAsync FormattedMessage:发生未处理的异常。主机正在关闭。
在我的Function入口点中有try..catch,但是这2个异常可能不会进入catch块。
我的host.json如下:
{
"functionTimeout": "00:10:00",
"version": "2.0",
"extensions": {
"queues": {
"maxPollingInterval": 1000,
"visibilityTimeout": "01:00:00",
"batchSize": 8,
"maxDequeueCount": 5,
"newBatchThreshold": 4
}
}
}
当我设置“ batchSize”:2和“ newBatchThreshold”:1时,冗余出队较少,但是创建了更多实例(通过记录每个Azure Function调用的服务器IP知道这一点)。如果我有更多服务器处理不同的消息,则在实例之间重复使用我的静态数据的可能性会降低。
还请注意,我已将“ visibilityTimeout”设置为1小时(我也尝试了30分钟),但看起来该值已被完全忽略,并且消息在10分钟后变为可见。
有什么想法可以避免重复处理相同的消息吗?我正在考虑在成功处理之后以及在每次消息出队时将消息信息写入DB,例如,检查此消息是否已处理,例如,从现在起1小时内;如果已处理,则不再进行处理。我正在考虑的另一个选项是将“ maxDequeueCount”设置为1(如果某些消息由于某些实际故障而根本无法处理,则我具有恢复机制)。
顺便说一句,那10%的冗余处理不会引起功能性问题,但是我仍然想提高性能。