一次性清除天蓝色服务总线队列

时间:2012-03-29 06:44:13

标签: .net azure queue azureservicebus azure-servicebus-queues

我们在项目中使用服务总线队列。当管理员选择清除队列时,我们需要一种功能来从队列中删除所有消息。我在网上搜索但找不到任何在QueueClient类中执行此操作的函数。

我是否必须逐个弹出所有消息,然后将其标记为完成以清除队列或者是否有更好的方法?

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

BrokeredMessage brokeredMessage = queueClient.Receive();

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

8 个答案:

答案 0 :(得分:8)

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

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

例如:

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

你可以使用hocho提到的ReceiveMode.ReceiveAndDelete再次使这个更简单。

答案 1 :(得分:5)

使用:

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

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);
}

答案 2 :(得分:2)

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

警告可能会返回消息的数量 n ,但无法保证。此外,邮件批量大小限制为256K

答案 3 :(得分: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;

答案 4 :(得分:2)

我使用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包。

答案 5 :(得分:1)

如果您使用的是来自nuget的WindowsAzure.Storage库,则可以使用简单的Clear()方法清除整个队列。我使用该库中的Microsoft.Windows.Azure.Queue类来管理队列。否则,您可以通过其API per their documentation进行访问。我不知道该方法在Azure库中存在了多长时间,并且在最初询问问题时它可能不存在,但REST API至少从2014年this Azure feedback post < / p>

使用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();

答案 6 :(得分:1)

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

如果您不担心过去 14 天(默认)存储的队列消息并想立即清除队列,那么 -

将 message time to live 值更改为 5 或 10 秒并等待 5-10 秒。所有队列消息将被清除。您可以再次重置原始值。默认为 14 天。

enter image description here

答案 7 :(得分:0)

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

对于这两种方法,您都可以使用最新的 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,它实际上并不从队列中删除消息 - 它告诉服务总线接收客户端想要显式 settle 接收到的消息。锁定部分意味着竞争接收者在锁定期间无法访问消息。