简体   繁体   English

我们可以使用 .net 代码从 Azure 服务总线中的死信队列中删除基于序列号的特定死信消息吗?

[英]can we delete a specific dead letter message based on the sequence number from dead letter queue in Azure service bus using .net code?

I have created a program to read the message from deadletter queue based on the sequence number and copy the contents of dead letter message and sends it to active queue as a new message with the content of deadletter message along with the same messageId and other properties.我创建了一个程序来根据序列号从死信队列中读取消息,并复制死信消息的内容并将其作为新消息发送到活动队列,其中包含死信消息的内容以及相同的 messageId 和其他属性。 And later I delete the same message from DLQ as well.后来我也从 DLQ 中删除了相同的消息。

 public static async Task<string> GetDeadLetterMessagesAsync(string connectionString,
string queueName, long seqNum, int countDLQMessages)
    {
        //creating a service bus client
        var serviceBusClient = new ServiceBusClient(connectionString);
        Console.WriteLine("ServiceBusClient is created");
        //ReceiverOptions to access dead letter queue
        var receiverOptions = new ServiceBusReceiverOptions { SubQueue = SubQueue.DeadLetter };
        Console.WriteLine("receiverOption is created");
        //Create receiver to access the deadletter queue of main queue
        var receiver = serviceBusClient.CreateReceiver(queueName, receiverOptions);
        Console.WriteLine("receiver is created");
        // serviceBusSender used to send the message to service bus
        ServiceBusSender sender;
        sender= serviceBusClient.CreateSender(queueName);
        
        IList<ServiceBusReceivedMessage> receivedMessages = (IList<ServiceBusReceivedMessage>)await receiver.ReceiveMessagesAsync(countDLQMessages);
        Console.WriteLine("read all the messages in service bus DLQ");
        var totalMessageCount = receivedMessages.Count;
        if (totalMessageCount == 0)
        {
            return "No Message is available in DLQ";
        }
        // Binary search on deadletter messages in DLQ on sequence number
        Int32 lower = 0;
            Int32 upper = receivedMessages.Count - 1;
            Console.WriteLine("ReceivedMessage List");
            Console.WriteLine(receivedMessages[0].Body);
            int sequenceFlag = 0;
            while (lower <= upper)
            {
                Int32 middle = lower + (upper - lower) / 2;
                if (seqNum == receivedMessages[middle].SequenceNumber)
                {
                    var Body = receivedMessages[middle].Body;
                    var MessageId = receivedMessages[middle].MessageId;
                    var CorrelationId = receivedMessages[middle].CorrelationId;
                    var msg = new ServiceBusMessage
                    {
                        Body = Body,
                        MessageId = MessageId,
                        CorrelationId = CorrelationId
                    };
                    //Sending the dead letter message to active queue along with its other properties i.e MessageId, etc.
                    await sender.SendMessageAsync(msg);
                    Console.WriteLine($"Message has been published from dead letter to Active Queue.");
                    //complete the dead letter message which will remove the message from dead letter queue
                    await receiver.CompleteMessageAsync(receivedMessages[middle]);
                    //Changing the sequenceFlag value to 1, if requested sequence number exists in DLQ.
                    sequenceFlag = 1;
                    //clean up the service bus resources used by sender and receiver
                    await sender.DisposeAsync();
                    await receiver.DisposeAsync();
                    break;
                }
                else if (seqNum < receivedMessages[middle].SequenceNumber)
                    upper = middle - 1;
                else
                    lower = middle + 1;
            }
       
        if (sequenceFlag != 1)
        {
            return ($"Sequence number: {seqNum} doesn't exist in queue - {queueName}");
        }
        else
        {
            return "Data is moved to Active queue";
        }
        
    }

This code works if we have less than 100 of messages in DLQ, but when we have more than 100 or 1000 of messages in DLQ, it doesn't read the dead letter messages available in DLQ and throws an output as message is not available for sequence number 'xyz'.如果我们在 DLQ 中的消息少于 100 条,则此代码有效,但是当我们在 DLQ 中的消息超过 100 或 1000 条时,它不会读取 DLQ 中可用的死信消息并抛出一个输出,因为消息不可用序列号'xyz'。 This issue happens due to the ReceiveMessagesAsync(MaxMessages) method, as it doesn't guarantee that it will return the exact same number of messages as requested in its parameter.此问题是由ReceiveMessagesAsync(MaxMessages)方法引起的,因为它不能保证返回与其参数中请求的消息数量完全相同的消息。

Do we have any other method from which we can extract n number of messages at once and can perform the further action on the same?我们是否有任何其他方法可以一次提取 n 条消息并对其执行进一步的操作?

I have Also tried to peek the message based on sequence number and sends its content to active queue as a new message but I am not able to complete that specific message in DLQ.我还尝试根据序列号查看消息并将其内容作为新消息发送到活动队列,但我无法在 DLQ 中完成该特定消息。

Can we delete/complete the dead letter message based on sequence number?我们可以根据序列号删除/完成死信消息吗?

Receiving N number of messages is not guaranteed when using the ReceiveMessageAsync method.使用 ReceiveMessageAsync 方法时不能保证接收 N 条消息。 If you need to receive N messages, you would need to loop until you've reached that amount, eg:如果您需要接收 N 条消息,则需要循环直到达到该数量,例如:

var remaining = numMessages;
var receivedMsgs = new List<ServiceBusReceivedMessage>();
while (remaining > 0)
{
    // loop in case we don't receive all messages in one attempt
    var received = await receiver.ReceiveMessagesAsync(remaining);
    receivedMsgs.AddRange(received);
    remaining -= received.Count;
}

Alternatively, if you are able to design your application in such a way that the messages can be deferred rather than deadlettered for this scenario, you can receive deferred messages directly based on the sequence number:或者,如果您能够以这样一种方式设计您的应用程序,即在这种情况下消息可以被延迟而不是死信,您可以直接根据序列号接收延迟消息:

var deferredMessage = await receiver.ReceiveDeferredMessageAsync(seqNumber);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 通过MessageId在Azure Service Bus死信队列上获取消息 - Getting a Message by MessageId on the Azure Service Bus Dead Letter queue Azure 服务总线 | 重新处理死信消息返回队列 | 如何接收来自死信队列的所有消息? - Azure service bus | Re process dead letter messages back to queue | How to receive all messages from dead letter queue? 如何在 Azure 服务总线中显式向主题订阅死信队列发送消息 - How to send message to Topic Subscription Dead Letter Queue Explicitly in Azure Service Bus 死信队列中的服务总线克隆不起作用 - Service Bus Clone from Dead Letter Queue Not Working 使用存储队列和服务总线时,Azure 死信队列和毒药队列有什么区别? - What is the difference between Azure Dead Letter Queues and Poison Queues when using Storage Queue and Service Bus? Azure Service Bus中死信队列中的邮件是否过期? - Do messages in dead letter queues in Azure Service Bus expire? 如何删除Azure Service Bus队列中的死信? - How do you delete the dead letters in an Azure Service Bus queue? 死信队列未清除 - Dead letter queue not cleared 如何使用MassTransit在Azure中为死信队列创建处理程序? - How I can create handler for dead-letter queue in Azure using MassTransit? 阅读服务总线主题订阅死信队列 (DLQ) C# 的最佳方式 - Best way to read Service Bus Topic Subscription Dead Letter Queue (DLQ) C#
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM