Функция и очередь Azure

#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 (видна на странице «Настройки» портала функций). Для получения более подробной информации вы могли бы обратиться к исправлению обновлений видимости очереди