23

We are using a service bus queue in our project. We are in need of a functionality to remove all the messages from the queue when the administrator chooses to clear the queue. I searched on the net but could not find any function which does this inside the QueueClient class.

Do I have to pop all the messages one by one and then marking them complete to clear the queue or is there a better way?

QueueClient queueClient = _messagingFactory.CreateQueueClient(
                              queueName, ReceiveMode.PeekLock);

BrokeredMessage brokeredMessage = queueClient.Receive();

while (brokeredMessage != null )
{
    brokeredMessage.Complete();
    brokeredMessage = queueClient.Receive();
}
4

8 回答 8

12

您可以从 azure 门户简单地执行此操作。

如果您不担心过去 14 天(默认)存储的队列消息并想立即清除队列,则将消息时间更改为 5 或 10 秒并等待 5-10 秒。

重要步骤:几秒钟后,尝试从队列接收以强制更新。

所有队列消息将被清除。您可以再次重置原始值。默认为 14 天。

在此处输入图像描述

于 2021-03-17T08:33:59.237 回答
9

像您一样在 while 循环中使用该Receive()方法将导致您的代码在队列为空时无限期地运行,因为该Receive()方法将等待另一条消息出现在队列中。

如果您希望它自动运行,请尝试使用该Peek()方法。

例如:

while (queueClient.Peek() != null)
{
    var brokeredMessage = queueClient.Receive();
    brokeredMessage.Complete();
}

您可以使用ReceiveMode.ReceiveAndDeletehocho 提到的方法再次简化此操作。

于 2014-02-11T10:52:51.483 回答
7

使用 :

  • 两种方法(来自@ScottBrady 和@participant)
  • MessageReceiver抽象

您可以编写一个清空服务总线队列或主题/订阅的方法:

MessageReceiver messageReceiver = ...
while (messageReceiver.Peek() != null)
{
    // Batch the receive operation
    var brokeredMessages = messageReceiver.ReceiveBatch(300);

    // Complete the messages
    var completeTasks = brokeredMessages.Select(m => Task.Run(() => m.Complete())).ToArray();

    // Wait for the tasks to complete. 
    Task.WaitAll(completeTasks);
}
于 2016-02-22T03:48:07.703 回答
5

使用ReceiveAndDeletePrefetchCountReceiveBatchAsync和简单的真值循环而不是使用 Peek的组合,我得到了很好的结果。下面是 MessagingFactory 的示例:

var receiverFactory = MessagingFactory.CreateFromConnectionString("ConnString");
var receiver = receiverFactory.CreateMessageReceiver("QName", ReceiveMode.ReceiveAndDelete);
receiver.PrefetchCount = 300;

bool loop = true;
while (loop)
{
    var messages = await receiver.ReceiveBatchAsync(300, TimeSpan.FromSeconds(1));
    loop = messages.Any();
}

仅需要WindowsAzure.ServiceBus Nuget 包。

于 2018-02-08T20:17:02.473 回答
2

对于 Azure-ServiceBus-Queues,有一个ReceiveBatch-method允许您同时接收一批n消息。结合ReceiveMode.ReceiveAndDelete您可以更有效地清除队列。

警告可能会返回n消息,但不能保证。消息批量大小也有256K的限制。

于 2015-01-13T09:12:04.553 回答
2

清理 Azure ServiceBus 队列的最快方法是设置一个非常短的DefaultMessageTimeToLive,等待几秒钟,尝试从队列中接收强制它更新,然后恢复初始的DefaultMessageTimeToLive.

您可以从门户网站或代码中执行此操作:

var namespaceManager = NamespaceManager.CreateFromConnectionString(connectionString);
var queueDescription = _namespaceManager.GetQueue(queueName);
var queueClient = QueueClient.CreateFromConnectionString(connectionString, queueName, ReceiveMode.ReceiveAndDelete);

var dl = queueDescription.EnableDeadLetteringOnMessageExpiration;
var ttl = queueDescription.DefaultMessageTimeToLive;

queueDescription.EnableDeadLetteringOnMessageExpiration = false;
queueDescription.DefaultMessageTimeToLive = TimeSpan.FromSeconds(1);

Thread.Sleep(5000);
var dumy = queueClient.ReceiveBatch(200, TimeSpan.FromSeconds(1)).ToArray();

queueDescription.EnableDeadLetteringOnMessageExpiration = dl;
queueDescription.DefaultMessageTimeToLive = ttl;
于 2016-07-07T21:55:18.233 回答
2

当我读到这个问题时,我首先想到的是为什么不删除并重新创建队列?这可能是一种方法。但如果不想这样做,您可以接收并删除每条消息,直到没有消息为止。

您可以将最新的 Azure 服务总线 .NET 库Azure.Messaging.ServiceBus用于这两种方法。

  1. 使用删除和重新创建队列AdministrationClient
using Azure.Messaging.ServiceBus.Administration;

ServiceBusAdministrationClient adminClient = new ServiceBusAdministrationClient("<connectionstring>");
await adminClient.DeleteQueueAsync("myqueue");          
await adminClient.CreateQueueAsync("myqueue");          

注意:适用于现有服务总线命名空间ServiceBusAdministrationClient上的 CRUD 操作。如果您还需要创建命名空间的能力,请改用Microsoft.Azure.Management.ServiceBus库。

  1. 接收并删除直到没有消息
using Azure.Messaging.ServiceBus;

await using var client = new ServiceBusClient("<connectionstring>");
                
ServiceBusReceiver receiver = client.CreateReceiver("myqueue", 
    new ServiceBusReceiverOptions { ReceiveMode = ServiceBusReceiveMode.ReceiveAndDelete });

while ((await receiver.PeekMessageAsync()) != null)
{
    // receive in batches of 100 messages.
    await receiver.ReceiveMessagesAsync(100);
}

ReceiveMode = ServiceBusReceiveMode.ReceiveAndDelete是不言自明的。默认接收模式PeekLock实际上并不从队列中删除消息 - 它告诉服务总线接收客户端想要明确地解决接收到的消息。锁定部分意味着竞争接收者在锁定期间无法访问消息。

于 2021-05-07T00:00:35.000 回答
1

Clear()如果您使用 nuget 中的 WindowsAzure.Storage 库,有一个简单的方法可以清除整个队列。我使用该Microsoft.Windows.Azure.Queue库中的类来管理队列。否则,您可以根据他们的文档通过他们的 API 访问。我不知道该方法在 Azure 库中存在多长时间,并且在最初提出问题时它可能不存在,但 REST API 至少可以追溯到 2014 年,根据Azure 反馈帖子

使用 Azure 库清除队列的完整 .NET 代码是:

string connectionString = "YourAzureConnectionStringHere";
string queueName = "YourWebJobQueueName";
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(connectionString);

// Create the queue client, then get a reference to queue
CloudQueueClient queueClient = storageAccount.CreateCloudQueueClient();
queue = queueClient.GetQueueReference(GetQueueName(queueName));

// Clear the entire queue
queue.Clear();
于 2018-01-11T20:30:05.650 回答