c# - 指定的消息不存在。错误代码 :MessageNotFound Prod-WorkerError Context

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

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

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](RESTCommand1 cmd, IRetryPolicy policy, OperationContext operationContext) --- Next Call Stack: at Microsoft.WindowsAzure.Storage.Core.Executor.Executor.ExecuteSync[T](RESTCommand1 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 block 中被捕获并记录下来。

我认为当辅助角色尝试删除队列中的消息但未找到该消息时存在一些问题。

需要有人帮助我解决此错误并了解这里出了什么问题的背景。

评论中提出的几个问题:

1) 您是否正在运行辅助角色的多个实例?

答:这是一个现有的应用程序,我发现我们正在使用ThreadPool来预实例化准备好工作的线程。

2) 您如何在工作角色中“获取”消息?您是否使用某种领导者选举模式来决定哪个实例接收消息?

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

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

答:设置为 120。

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

答:我对此不太确定。

最佳答案

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

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

如果您尝试使用旧的 popreceipt 值在消息再次出列(通过其他进程)时删除该消息,您将收到您所收到的错误。

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

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

关于c# - 指定的消息不存在。错误代码 :MessageNotFound Prod-WorkerError Context,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39699614/

相关文章:

c# - 将属性传递给方法时更清晰的实现

c# - 非泛型 IEnumerable 到字符串

iis - IIS中的MVC3结构

asp.net-mvc-3 - ASP.NET MVC 3 HttpPost 操作方法未找到

c# - 模拟、Active Directory 和 "user does not have authority to xxxx"问题

c# - 从数据库中提取数据时,如何在 GridView 中仅显示日期? C#

asp.net - jwplayer 的 crossdomain.xml 文件的访问路径

c# - 在长时间访问期间,隐藏字段是否比 session 更好地存储值

c# - 从 MP4 视频中提取 JPG 图像

c# - 非英语窗口系统上的语音识别