指定的消息不存在。 ErrorCode:MessageNotFound Prod-WorkerError Context

时间:2016-09-26 09:50:25

标签: c# asp.net asp.net-mvc-3 azure queue

我有一个辅助角色,它使用Azure队列中的消息在后台进行一些处理。 当我检查我的日志时,在处理消息时似乎没有记录异常,但仍然在我的日志中我得到以下异常(仅从长错误日志中粘贴一些相关文本):

  

System.Net.WebException   Microsoft.WindowsAzure.Storage.StorageException异常消息:   远程服务器返回错误:(404)Not Found。遥控器   服务器返回错误:(404)未找到。堆栈痕迹: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策略,OperationContext operationContext)at   Microsoft.WindowsAzure.Storage.Queue.CloudQueue.DeleteMessage(字符串   messageId,String popReceipt,QueueRequestOptions选项,   OperationContext operationContext)at   InnovativeExams.Azure.CloudStorage.AzureQueue`1.DeleteMessage(T   message)指定的消息不存在。   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块中捕获并记录。

我认为当worker角色尝试删除队列中的消息并且找不到消息时会出现问题。

需要某人的帮助才能帮助我解决此错误并了解背景中出现的问题。

评论中提出的问题很少:

1)您是否正在运行工作者角色的多个实例?

答:这是一个现有的应用程序,我发现我们正在使用 ThreadPool 来预先实例化,这些线程已准备就绪。

2)你好吗&#34;得到&#34;你的工作者角色中的消息?您是否正在使用某种领导者选举模式来决定哪个实例获取消息?

答:是的,有一个框架可以确定要处理的QueueMessage的相应调度程序。

3)当您收到消息时,这些消息的可见性超时是什么?

答:它设定为120.

4)您需要多长时间处理这些消息,即获取消息和删除消息之间需要多长时间?

答:我不确定。

1 个答案:

答案 0 :(得分:2)

让我解释一下,在什么情况下你会得到你遇到的错误。

当您将消息出列队列(即Azure术语中的GET Messages)时,Azure队列服务会返回名为popreceipt的内容,该内容必须用于删除或更新消息。这个popreceipt是一个不透明的值(即你不应该在它周围构建任何业务逻辑),它在相同的消息再次出列之前一直有效。当邮件再次出列时,您将获得popreceipt的新值,您应该使用此新值来删除或更新邮件。

如果您尝试使用旧的popreceipt值来删除邮件,而邮件再次出列(通过其他一些过程),您将收到错误。

我的猜测是,这就是你的应用程序中发生的事情。请检查是否确实如此:

其中一个辅助角色实例使消息出列并开始处理该消息。根据您上面所说的内容,您在消息出列时隐藏消息120秒。我假设处理消息所花费的实际时间超过120秒,因此消息重新出现在队列中。现在有另一个进程将此消息出列(因此您获得了新的popreceipt)。但是,在第二个进程将消息出列后不久,第一个进程就完成了对消息的处理,现在它想要使用它所拥有的popreceipt来删除消息。由于此popreceipt不再有效,因此使用此popreceipt对该消息执行删除操作的任何尝试都将导致找不到消息错误。