2016-09-26 1 views
0

У меня есть рабочая роль, которая потребляет сообщения из очереди Azure, выполняет некоторую обработку в фоновом режиме. Когда я просматриваю журнал, кажется, нет быть не исключение регистрируется при обработке сообщения, но все еще в моих журналах я получаю следующее исключение (наклеивая некоторые из соответствующих текстов только из длинного протокола ошибок):Указанное сообщение не существует. ErrorCode: MessageNotFound Prod-WorkerError Context

System.Net.WebException Microsoft.WindowsAzure.Storage.StorageException Exception messages: The remote server returned an error: (404) Not Found. The remote server returned an error: (404) Not Found. Stack Traces: at System.Net.HttpWebRequest.GetResponse() at Microsoft.WindowsAzure.Storage.Core.Executor.Executor.ExecuteSync[T](RESTCommand 1 cmd, IRetryPolicy policy, OperationContext operationContext) --- Next Call Stack: at Microsoft.WindowsAzure.Storage.Core.Executor.Executor.ExecuteSync[T](RESTCommand 1 cmd, IRetryPolicy policy, OperationContext operationContext) at Microsoft.WindowsAzure.Storage.Queue.CloudQueue.DeleteMessage(String messageId, String popReceipt, QueueRequestOptions options, OperationContext operationContext) at InnovativeExams.Azure.CloudStorage.AzureQueue`1.DeleteMessage(T message) The specified message does not exist. ErrorCode:MessageNotFound Prod-WorkerError Context

Здесь это код, который у меня есть в рабочей роли:

private void ProcessQueueMessage(object queueMessageToProcess) 
     { 
      var queueMessage = queueMessageToProcess as EventCompletedQueueMessage; 

      try 
      { 
       if (_eventCompletedProcessor.Process(queueMessage)) 
        _azureQueue.DeleteMessage(queueMessage); 
      } 
      catch (Exception ex) 
      { 
       _logger.LogError(string.Format("Event Completed message <{0}> was not processed due to an exception", queueMessage.Id), ex, LogSources.WorkerRole_EventCompletedDispatcher); 
      } 
     } 

Вышеупомянутое исключение попадает в вышеупомянутый блок catch и регистрируется.

Я думаю, что есть некоторая проблема, когда рабочая роль пытается удалить сообщение в очереди и сообщение не найдено.

Нужна помощь от кого-то, чтобы помочь мне разрешить эту ошибку и узнать фон, что здесь не так.

Несколько вопросов задают в комментариях:

1) Вы используете несколько экземпляров вашего рабочего роли?

A: Это уже существующее приложение, и я выяснил, что мы используем ThreadPool для предварительной реализации, потоки, которые готовы к работе.

2) Как вы получаете сообщения в своей рабочей роли? Используете ли вы какую-то модель выбора лидеров, чтобы решить, какой экземпляр получает сообщения?

A: Да, существует инфраструктура, которая определяет соответствующий диспетчер для обработки QueueMessage.

3) Когда вы получаете сообщения, какой тайм-аут видимости для этих сообщений?

A: Его набор 120.

4) Сколько времени потребуется для вас, чтобы обработать эти сообщения, т.е. сколько времени между получением сообщения и удалять сообщения?

A: Я не уверен в этом.

+0

Несколько вопросов (Пожалуйста, обновите свой вопрос с ответами на эти вопросы): 1) Вы используете несколько экземпляров вашей рабочей роли? 2) Как вы «получаете» сообщения в своей рабочей роли? Используете ли вы какую-то модель выбора лидеров, чтобы решить, какой экземпляр получает сообщения? 3) Когда вы получаете сообщения, какой тайм-аут видимости для этих сообщений? 4) Сколько времени вам нужно для обработки этих сообщений, т. Е. Сколько времени между получением сообщения и удалением сообщений? –

+0

@ GauravMantri Отредактировал вопрос. Пожалуйста, проверьте. – Maninder

ответ

2

Позвольте мне объяснить, в какой ситуации вы получите ошибку, с которой вы сталкиваетесь.

Когда вы удаляете сообщение (т. Е. GET Messages по лазурной терминологии), служба очереди Azure возвращает что-то под названием popreceipt, которое должно использоваться для удаления или обновления сообщения. Этот является непрозрачным значением (т. Е. Вы не должны создавать вокруг него какую-либо бизнес-логику), которая остается действительной до тех пор, пока не удастся снова удалить одно и то же сообщение. Когда сообщение снова вычеркнуто, вы получите новое значение для popreceipt, и вы должны использовать это новое значение для удаления или обновления сообщения.

Если вы пытаетесь использовать старое значение popreceipt, чтобы удалить сообщение, когда сообщение снова было отменено (каким-либо другим процессом), вы получите сообщение об ошибке, которую вы получаете.

Я предполагаю, что это то, что происходит в вашем приложении.Пожалуйста, проверьте, действительно ли это так:

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

+0

Спасибо Gaurav за подробное объяснение деталей PopPeceipt. Я тоже принимал ту же ситуацию, но не знал в глубине этого. Я попробую добавить секундомер, а затем посмотрю, сколько времени потребуется для обработки сообщений, и соответственно обновит видимость очереди. – Maninder

Смежные вопросы