azure - 完成 Azure 服务总线上死信队列中的消息

标签 azure azureservicebus azure-servicebus-queues

我希望能够从死信队列中删除选定的消息。

这是如何实现的?

我不断收到错误:

操作无法完成,因为 RecieveContext 为 Null

我已经尝试了我能想到和读到的所有方法,这就是我现在的位置:

public void DeleteMessageFromDeadletterQueue<T>(string queueName, long sequenceNumber)
        {
     var client = GetQueueClient(queueName, true);
                var messages = GetMessages(client);
                foreach(var m in messages)
                {
                    if(m.SequenceNumber == sequenceNumber)
                    {
                        m.Complete();
                    }
                    else
                    {
                        m.Abandon();
                    }
                }
}

/// <summary>
        /// Return a list of all messages in a Queue
        /// </summary>
        /// <param name="client"></param>
        /// <returns></returns>
        private IEnumerable<BrokeredMessage> GetMessages(QueueClient client)
        {
            var peekedMessages = client.PeekBatch(0, peekedMessageBatchCount).ToList();
            bool getmore = peekedMessages.Count() == peekedMessageBatchCount ? true : false;

            while (getmore)
            {
                var moreMessages = client.PeekBatch(peekedMessages.Last().SequenceNumber, peekedMessageBatchCount);
                peekedMessages.AddRange(moreMessages);
                getmore = moreMessages.Count() == peekedMessageBatchCount ? true : false;
            }

            return peekedMessages;
        }

不知道为什么这似乎是一项艰巨的任务。

最佳答案

这里的问题是您调用了 PeekBatch,它返回刚刚查看的消息。没有可用于完成或放弃消息的接收上下文。即使将 receiveMode 设置为 PeekLock,Peek 和 PeekBatch 操作也仅返回消息并且根本不锁定消息。它主要用于浏览队列,但您无法对它们采取操作。请注意文档中的“放弃”和“完成”状态,“只能在使用以 Peek-Lock ReceiveMode 操作的接收器接收到的消息上调用”。这里不清楚,但 Peek 和 PeekBatch 操作不计入其中,因为它们实际上并没有获得接收上下文。这就是当您尝试调用放弃时它会失败的原因。如果您确实找到了您要查找的内容,那么当您调用 Complete 时,它​​会抛出不同的错误。

您想要做的是在 PeekBatch RecieveMode 中使用 ReceiveBatch 操作。这实际上会拉回一批消息,然后当您查看它们以找到您想要的消息时,您实际上可以影响消息的完整性。当您触发放弃时,它会立即将不是您想要的消息释放回队列。

如果您的死信队列非常小,通常这不会太糟糕。如果它真的很大,那么采用这种方法并不是最有效的。您将死信队列更像是一个堆并对其进行挖掘,而不是“按顺序”处理消息。在处理需要手动干预的死信队列时,这种情况并不罕见,但如果您有很多死信队列,那么最好将死信队列处理到不同类型的存储中,这样您可以更轻松地找到和处理死信队列。销毁消息,但仍然可以重新创建可以推送到不同队列进行重新处理的消息。

如果您手动进行死字处理,可能还有其他选项,例如使用 Defer。请参阅How to use the MessageReceiver.Receive method by sequenceNumber on ServiceBus

关于azure - 完成 Azure 服务总线上死信队列中的消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33620999/

相关文章:

node.js - 如何使用 Azure 移动服务调度程序解析 RSS 文件

azure - Azure ServiceBus QueueClient.OnMessage 是否在不同的线程上执行

azureservicebus - Azure 服务总线 - 未经授权的访问。执行此操作需要 'Send' 声明

Azure 服务总线 - 放弃的消息返回到同一订阅者

azure - 将 SQL 存储过程 ResultSet 表 JSON 转换为 XML

azure - 将文件名从 Foreach 传递到数据流 - Azure 数据工厂

azure - AKKA 是否尝试在内存中执行与 Azure 服务总线队列在磁盘上执行的操作相同的操作?

Azure Function ServiceBusTrigger 在几毫秒内多次触发同一消息,而无需第一次完成

c# - 为什么我无法使用 Azure 服务总线队列获取队列消息?

javascript - 如何使用 JavaScript API 执行服务器端 Cosmos DB Patch?