[英]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.