c# – 通过MessageId在Azure Service Bus Dead Letter队列中获取消息

前端之家收集整理的这篇文章主要介绍了c# – 通过MessageId在Azure Service Bus Dead Letter队列中获取消息前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在编写用于监视和修复Azure上主题订阅的死信队列中的消息的功能.

我可以使用_subscriptionClient.PeekBatch(10)来显示消息列表;但是,当我们想要实际删除其中一条消息时,我们会陷入困境.

工作流程将是:

>获取所有消息的列表
>将特定消息(例如集合中的第5个)发送回原始队列以进行重新处理
>将关联的死信消息标记为.Complete().

问题是,虽然我们有消息列表,但我们不能在不使用.subscriptionClient.Receive()的情况下调用特定的消息列表上的.Complete().

你不能.通过MessageId接收消息(),这是否意味着我们必须像下面一样逐个循环消息?

public BrokeredMessage GetMessageById(string messageIdentifier)
{
    BrokeredMessage matchingMessage = null;
    var messageNotFound = true;

    var messagesToAbandon = new List<BrokeredMessage>();

    while (messageNotFound)
    {
        var message = _subscriptionClient.Receive();

        if (message == null)
        {
            throw new Exception("Could not find the message on the queue");
        }

        if (message.MessageId == messageIdentifier)
        {
            messageNotFound = false;
            matchingMessage = message;
        }
        else
        {
            messagesToAbandon.Add(message);
        }
    }

    // Unlock all messages that do not match the matching one received.
    foreach (var message in messagesToAbandon)
    {
        message.Abandon();
    }

    return matchingMessage;
}

我对这种方法的问题是:

>它不可扩展;如果消息是集合中的第100个怎么办?我们必须循环到99并将每个标记为废弃
>如果要放弃的项目太多,我们可能会失去对matchMessage的锁定
>这是一个漫长的过程

如果在循环中不匹配,我已经玩弄了将每条消息标记为已放弃的想法;然而,这会产生我们无限循环遍历相同项目的风险(因为.Abandon()将它们放回队列中).

有没有人找到一个有效的方法呢?也许使用.Defer()和.Receive(sequenceNumber)?

解决方法

您可以在此处使用会话,为每条消息设置会话ID.稍后当您浏览DeadLetter时,选择消息及其sessionID,使用sessionID打开会话并在消息上接收.

更新:
作为特殊队列的DeadLetter队列不允许会话,并且也不能使用sequenceNumber从DeadLetter队列接收消息,如果您想要选择消息,这些是我找到的两个选项.

所以这是在所述情况下应该做的事情,从DeadLetter获取所有消息,将某些消息重播到原始队列以进行重新处理,将其余消息移动到另一个队列(ErrorQueue)并清除死信队列.我认为这更合适,因为DeadLetter队列更像是ServicBus处理错误/到期的内部队列.如果应用程序需要处理错误,那么将它们移动到特定于应用程序的队列将提供更大的灵活性,而不是过载系统队列(DeadLetter Queue)

猜你在找的C#相关文章