Функция Azure для запуска очереди: сообщения очереди обрабатываются более одного раза - PullRequest
0 голосов
/ 09 января 2019

У меня есть функция Azure HTTP-триггера, которая добавляет сообщение в очередь: outputQueue.AddAsync (myMessage); Затем запускается функция Azure, запускающая очередь. Он добавляет 100 сообщений в одну очередь. Каждое из этих 100 сообщений удаляется этой функцией и обрабатывается. Эта обработка занимает около 5-7 минут. Моя функция Timeout составляет 10 минут. Иногда (в 10% вызовов) одно и то же сообщение удаляется из очереди и обрабатывается дважды и даже больше, хотя предыдущая обработка этого сообщения была успешной. Также я обратил внимание на то, что каждая такая избыточная очередь происходит примерно через 10 минут после предыдущей очереди того же самого массажа (кажется, это связано с моей функцией Timeout 10 минут). Таким образом, похоже, что после завершения обработки функция не завершается и, следовательно, не удаляется из очереди, что приводит к тому, что другой экземпляр удаляет ее из очереди.

Когда я смотрю на раздел «Сбои» в Application Insights, я вижу, что примерно для операций с 1 КБ у меня есть около 10 исключений WebExceptions и 2 TimeoutExceptions.

WebException:

Сообщение: удаленный сервер возвратил ошибку: (409) Конфликт. Неудачный метод: Microsoft.WindowsAzure.Storage.Shared.Protocol.HttpResponseParsers.ProcessExpectedStatusCodeNoExceptiond FormattedMessage: произошло необработанное исключение. Хост закрывается.

TimeoutException:

Сообщение: клиент не смог завершить операцию в течение указанного времени ожидания. Клиент не смог завершить операцию в течение указанного времени ожидания. Сбой метода: Microsoft.WindowsAzure.Storage.Core.Executor.Executor.EndExecuteAsync FormattedMessage: произошло необработанное исключение. Хост закрывается.

У меня есть 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 у меня меньше избыточных очередей, но создается больше экземпляров (я знаю это, регистрируя IP-адрес сервера каждого вызова функции Azure). Если у меня больше серверов, которые обрабатывают разные сообщения, тогда мои статические данные реже используются между экземплярами.

Также обратите внимание, что я установил «visibilityTimeout» на 1 час (я тоже пробовал 30 минут), но похоже, что это значение полностью игнорируется, и сообщение становится видимым через 10 минут.

Есть идеи, как избежать дублирования в обработке одних и тех же сообщений? Я подумываю о том, чтобы записать информацию о сообщении в БД после успешной обработки и при каждой очереди сообщения проверять, было ли обработано это сообщение, скажем, в течение 1 часа и, если да, не обрабатывать его снова. Еще одна опция, о которой я думаю, - установить для параметра maxDequeueCount значение 1 (у меня есть механизм восстановления, если некоторые сообщения вообще не будут обрабатываться из-за какого-либо реального сбоя).

Кстати, эти 10% избыточных обработок не вызывают проблем с функциональностью, но я все еще хочу улучшить производительность.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...