死信队列未清除
Dead letter queue not cleared
我有几条消息由于重试次数超出而自动变成死信。现在我正在尝试像这样重新排队:
while ((msg = DeadLetterQueueClient.Receive()) != null)
{
var body = msg.GetBody<MyModel>();
QueueClient.Send(new BrokeredMessage(body));
}
我收到了所有死信消息,但是它们没有从队列中清除。每次我启动此代码时,都会再次收到相同的消息。
怎么了?
PS:根据旧的 Azure 门户,队列实际上已关闭死信。这些消息仅在 Visual Studio Server Explorer 中显示为死信,我也收到了带有上述代码的消息。
将消息标记为已完成,应将其从死信队列中删除
while ((msg = DeadLetterQueueClient.Receive()) != null)
{
var body = msg.GetBody<MyModel>();
QueueClient.Send(new BrokeredMessage(body));
msg.Complete();
}
如果您想保留 header 属性,您可能需要使用 msg.Clone() 而不是将 body 复制到新的 BrokeredMessage 中。
您也可以尝试使用此代码从队列中删除死信消息。
MessageReceiver fromQueueClient = null;
MessagingFactory factory = MessagingFactory.CreateFromConnectionString(connectionString);
fromQueueClient = await factory.CreateMessageReceiverAsync(_entityName, ReceiveMode.PeekLock);
BrokeredMessage _message = await fromQueueClient.ReceiveAsync(SequenceNumber);
await _message.CompleteAsync();
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.Azure.ServiceBus;
using Microsoft.Azure.ServiceBus.Core;
using System.Text;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace ClearDeadLetterQ
{
[TestClass]
public class UnitTest1
{
const string ServiceBusConnectionString = "Endpoint=sb://my-domain.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=yoursharedaccesskeyhereyoursharedaccesskeyhere";
[TestMethod]
public async Task TestMethod1()
{
await this.ClearDeadLetters("my.topic.name", "mysubscriptionname/$DeadLetterQueue");
}
public async Task ClearDeadLetters(string topicName, string subscriptionName)
{
var messageReceiver = new MessageReceiver(ServiceBusConnectionString, EntityNameHelper.FormatSubscriptionPath(topicName, subscriptionName), ReceiveMode.PeekLock);
var message = await messageReceiver.ReceiveAsync();
while ((message = await messageReceiver.ReceiveAsync()) != null)
{
await messageReceiver.CompleteAsync(message.SystemProperties.LockToken);
}
await messageReceiver.CloseAsync();
}
}
}
我有几条消息由于重试次数超出而自动变成死信。现在我正在尝试像这样重新排队:
while ((msg = DeadLetterQueueClient.Receive()) != null)
{
var body = msg.GetBody<MyModel>();
QueueClient.Send(new BrokeredMessage(body));
}
我收到了所有死信消息,但是它们没有从队列中清除。每次我启动此代码时,都会再次收到相同的消息。
怎么了?
PS:根据旧的 Azure 门户,队列实际上已关闭死信。这些消息仅在 Visual Studio Server Explorer 中显示为死信,我也收到了带有上述代码的消息。
将消息标记为已完成,应将其从死信队列中删除
while ((msg = DeadLetterQueueClient.Receive()) != null)
{
var body = msg.GetBody<MyModel>();
QueueClient.Send(new BrokeredMessage(body));
msg.Complete();
}
如果您想保留 header 属性,您可能需要使用 msg.Clone() 而不是将 body 复制到新的 BrokeredMessage 中。
您也可以尝试使用此代码从队列中删除死信消息。
MessageReceiver fromQueueClient = null;
MessagingFactory factory = MessagingFactory.CreateFromConnectionString(connectionString);
fromQueueClient = await factory.CreateMessageReceiverAsync(_entityName, ReceiveMode.PeekLock);
BrokeredMessage _message = await fromQueueClient.ReceiveAsync(SequenceNumber);
await _message.CompleteAsync();
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.Azure.ServiceBus;
using Microsoft.Azure.ServiceBus.Core;
using System.Text;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace ClearDeadLetterQ
{
[TestClass]
public class UnitTest1
{
const string ServiceBusConnectionString = "Endpoint=sb://my-domain.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=yoursharedaccesskeyhereyoursharedaccesskeyhere";
[TestMethod]
public async Task TestMethod1()
{
await this.ClearDeadLetters("my.topic.name", "mysubscriptionname/$DeadLetterQueue");
}
public async Task ClearDeadLetters(string topicName, string subscriptionName)
{
var messageReceiver = new MessageReceiver(ServiceBusConnectionString, EntityNameHelper.FormatSubscriptionPath(topicName, subscriptionName), ReceiveMode.PeekLock);
var message = await messageReceiver.ReceiveAsync();
while ((message = await messageReceiver.ReceiveAsync()) != null)
{
await messageReceiver.CompleteAsync(message.SystemProperties.LockToken);
}
await messageReceiver.CloseAsync();
}
}
}