#queue #azure-storage #azure-functions #message-queue #azure-storage-queues
#очередь #azure-хранилище #azure-функции #очередь сообщений #azure-storage-очереди
Вопрос:
У меня есть функция:
public async static Task Run([QueueTrigger("efs-api-call-last-datetime", Connection = "StorageConnectionString")]DateTime queueItem,
[Queue("efs-api-call-last-datetime", Connection = "StorageConnectionString")]CloudQueue inputQueue,
TraceWriter log)
{
Затем у меня есть длительный процесс обработки сообщения из очереди. Проблема в том, что сообщение будет повторно отправлено в очередь через 30 секунд, пока я обрабатываю это сообщение. Мне не нужно добавлять это сообщение и обрабатывать его дважды.
Я хотел бы иметь код, подобный:
try
{
// long operation
}
catch(Exception ex)
{
// something wrong. Readd this message in 1 minute
await inputQueue.AddMessageAsync(new CloudQueueMessage(
JsonConvert.SerializeObject(queueItem)),
timeToLive: null,
initialVisibilityDelay: TimeSpan.FromMinutes(1),
options: null,
operationContext: null
);
}
и предотвратите ее автоматическое чтение. Есть какой-нибудь способ это сделать?
Ответ №1:
Здесь есть несколько моментов.
1) Когда в очереди ожидают несколько сообщений, триггер очереди извлекает пакет сообщений и одновременно вызывает экземпляры функции для их обработки. По умолчанию размер пакета равен 16. Но это настраивается в Host.json. Вы можете установить размер пакета равным 1, если хотите свести к минимуму параллельное выполнение. Это объясняется в документе Microsoft.
2) Поскольку это длительный процесс, поэтому кажется, что ваши сообщения не завершены, и функция может подождать, и сообщение снова будет видно. Вы должны попытаться разбить свою функцию на более мелкие функции. Затем вы можете использовать долговременную функцию, которая свяжет работу, которую вам нужно выполнить.
Ответ №2:
Да, одно и то же сообщение можно удалить из очереди дважды.
Причины:
1. Работник A удаляет сообщение B из очереди, и время ожидания невидимости истекает. Сообщение B снова становится видимым, и работник C удаляет сообщение B из очереди, делая недействительной всплывающую квитанцию работника A. Рабочий A заканчивает работу, переходит к удалению сообщения B и выдается ошибка. Это наиболее распространенное.
2. Срок действия блокировки исходного сообщения, которое запускает выполнение первой функции Azure, вероятно, истекает. Это заставит очередь предположить, что обработка сообщения завершилась неудачно, и затем она будет использовать это сообщение для повторного запуска функции.
3.In при определенных условиях (очень частый опрос очереди) вы можете получить одно и то же сообщение дважды на GetMessage
. Это тип состояния гонки, которое, хотя и редко, все же возникает. Рабочие A и B опрашивают очень быстро и попадают в очередь одновременно, и оба получают одно и то же сообщение. Раньше это было гораздо более распространенным явлением (временные рамки SDK 1.0) в сценариях с высокой частотой опроса, но теперь это стало намного реже в более поздних обновлениях хранилища (не могу вспомнить, чтобы видел это недавно).
1 и 3 выполняются только тогда, когда у вас более 1 работника.
Обходной путь:
Установите azure-webjobs-sdk
версию 1.0.11015.0 (видна на странице «Настройки» портала функций). Для получения более подробной информации вы могли бы обратиться к исправлению обновлений видимости очереди