首页 文章

如何在Azure Service Bus主题上删除DeadLetter消息

提问于
浏览
8

我正在写一段代码,这将允许我们:

  • 查看Azure Service Bus主题(Peek)中存在的所有死信消息的列表

  • 修复并将其发回主题

  • 重新发送时从死信队列中删除它们 .

前2分我没有问题;使用Peek接收模式,我可以显示消息列表,我们可以编辑和重新发送,没有任何问题 .

当我想从死信队列中删除消息时,问题就来了 .

我们如何通过消息级别对消息执行此操作?我们可能只想删除驻留在死信队列中的2条消息,并保留其他消息以便稍后查看 . 在死信队列中的消息上调用 .Complete() 是否像在主订阅中那样删除它?

以供参考;这是我们为死信队列获取 SubscriptionClient 的代码:

private SubscriptionClient GetOrCreateSubscriptionClient(string connectionString)
{
    if (!NamespaceManager.TopicExists(_topicName))
    {
        NamespaceManager.CreateTopic(new TopicDescription(_topicName)
        {
            MaxSizeInMegabytes = 5120,
            DefaultMessageTimeToLive = TimeSpan.FromSeconds(DEFAULT_LOCK_DURATION_IN_SECONDS)
        });
    }

    if (!NamespaceManager.SubscriptionExists(_topicName, _subscriptionName))
    {
        NamespaceManager.CreateSubscription(_topicName, _subscriptionName);
    }

    var deadLetterPath = SubscriptionClient.FormatDeadLetterPath(_topicName, _subscriptionName);

    var client = SubscriptionClient.CreateFromConnectionString(
        connectionString, deadLetterPath, _subscriptionName, ReceiveMode.PeekLock);

    return client;

}

2 回答

  • 0

    是的,对从死信队列中收到的代理消息的引用调用完成将从死信队列中删除它 .

  • 8

    以下是如何获取死信队列中所有消息的列表:

    public async Task<IEnumerable<BrokeredMessage>> GetDeadLetterMessagesAsync(string connectionString,
        string queueName)
    {
        var queue = QueueClient.CreateFromConnectionString(connectionString, QueueClient.FormatDeadLetterPath(queueName));
        var messageList = new List<BrokeredMessage>();
        BrokeredMessage message;
        do
        {
            message = await queue.PeekAsync();
            if (message != null)
            {
                messageList.Add(message);
            }
        } while (message != null);
        return messageList;
    }
    

    然后使用SequenceNumber删除特定消息:

    public async Task DeleteDeadLetterMessageAsync(string connectionString, string queueName, long sequenceNumber)
    {
        var deadLetterQueue = QueueClient.CreateFromConnectionString(connectionString, QueueClient.FormatDeadLetterPath(queueName));
        var msg = await deadLetterQueue.PeekAsync(sequenceNumber);
        if (msg.SequenceNumber == sequenceNumber)
        {
            msg = await deadLetterQueue.ReceiveAsync();
            await msg.CompleteAsync();
        }
    }
    

    请注意,如果没有任何带有指定SequenceNumber的消息,Peek可能会返回另一条消息 . 因此,您需要检查SequenceNumber,以便不删除错误的消息 .

相关问题