简体   繁体   English

清除 azure 服务总线队列 go

[英]Clearing azure service bus queue in one go

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.我在 .net 上搜索但找不到在QueueClient class 中执行此操作的任何 function。

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

Using the Receive() method within the while loop like you are will cause your code to run indefinitely once the queue is empty, as the Receive() method will be waiting for another message to appear on the queue. 像往常一样在while循环中使用Receive()方法将导致代码在队列为空时无限期地运行,因为Receive()方法将等待另一条消息出现在队列中。

If you want this to run automatically, try using the Peek() method. 如果您希望自动运行,请尝试使用Peek()方法。

For example: 例如:

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

You can make this simpler again with the ReceiveMode.ReceiveAndDelete as was mentioned by hocho. 您可以使用hocho提到的ReceiveMode.ReceiveAndDelete再次使这更简单。

You can simply do this from azure portal.您可以简单地从 azure 门户执行此操作。

If you are not worried about queue messages stored in past 14 days (default) and wanted to clear queue immediately then change message time to live value to 5 or 10 seconds and wait for 5-10 seconds.如果您不担心过去 14 天(默认)存储的队列消息并想立即清除队列,则将消息生存时间值更改为 5 或 10 秒并等待 5-10 秒。

Important step: After a few seconds, try to receive from queue to force it to update.重要步骤:几秒钟后,尝试从队列接收以强制其更新。

All queue messages will be cleared.所有队列消息将被清除。 you can again reset original value.您可以再次重置原始值。 default is 14 days.默认为 14 天。

在此处输入图片说明

Using : 使用:

  • Both approach (from @ScottBrady and @participant) 两种方法(来自@ScottBrady和@participant)
  • And the MessageReceiver abstraction MessageReceiver抽象

you can write a method that empty a service bus queue or a topic/subscription: 您可以编写一个清空服务总线队列或主题/订阅的方法:

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

I'm having good results using a combination of ReceiveAndDelete , PrefetchCount , ReceiveBatchAsync , and a simple truth loop rather than using Peek. 我使用ReceiveAndDeletePrefetchCountReceiveBatchAsync和一个简单的真值循环,而不是使用Peek,结果很好。 Example with MessagingFactory below: 下面的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();
}

Only requires the WindowsAzure.ServiceBus Nuget package. 只需要WindowsAzure.ServiceBus Nuget包。

For Azure-ServiceBus-Queues there is a ReceiveBatch -method which allows you to receive a batch of n -messages at the time. 对于Azure-ServiceBus-Queues,有一个ReceiveBatch -method ,它允许您当时接收一批n- message。 Combined with ReceiveMode.ReceiveAndDelete you can clear the queue more efficiently. 结合ReceiveMode.ReceiveAndDelete您可以更有效地清除队列。

Caveat The number n of messages might be returned but it's not guaranteed. 警告可能会返回消息数n ,但不能保证。 Also there is a limit for the message-batch size of 256K . 此外,邮件批量大小限制为256K

The fastest way to clean a Azure ServiceBus Queue is to set a very short DefaultMessageTimeToLive , wait a few second, try receive from queue from force it to update then restore the initial DefaultMessageTimeToLive . 清理Azure ServiceBus队列的最快方法是设置一个非常短的DefaultMessageTimeToLive ,等待几秒钟,尝试从队列接收强制它更新然后恢复初始DefaultMessageTimeToLive

You can do it from the portal or from code : 您可以从门户网站或代码中执行此操作:

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;

There is a simple Clear() method to clear the entire queue if you are using the WindowsAzure.Storage library from nuget. 如果您使用的是来自nuget的WindowsAzure.Storage库,则有一个简单的Clear()方法可以清除整个队列。 I use the Microsoft.Windows.Azure.Queue class from that library to manage the queue. 我使用该库中的Microsoft.Windows.Azure.Queue类来管理队列。 Otherwise, you can access via their API per their documentation . 否则,您可以根据其文档通过其API访问。 I don't know how long the method has been in the Azure library and it probably didn't exist when the question was originally asked, but the REST API stems back from at least 2014 per this Azure feedback post 我不知道该方法在Azure库中存在多长时间,并且在最初询问问题时它可能不存在,但REST API至少源自2014年Azure反馈帖子的 2014年

The full .NET code to clear the queue with the Azure library is: 使用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();

The first I thought I had when I read the question was why not delete and recreate the queue?当我读到这个问题时,我首先想到的是为什么不删除并重新创建队列? That could be an approach.这可能是一种方法。 But if don't want to do that, you can receive and delete each message until there's no message left.但如果不想这样做,您可以接收和删除每条消息,直到没有消息为止。

You can use the latest Azure Service Bus .NET library Azure.Messaging.ServiceBus for both approaches.您可以将最新的 Azure 服务总线 .NET 库Azure.Messaging.ServiceBus用于这两种方法。

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

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

Note: ServiceBusAdministrationClient is for CRUD operations on an already existing Service Bus namespace.注意: ServiceBusAdministrationClient用于对现有服务总线命名空间的 CRUD 操作。 If you also need the ability to create a namespace, use the Microsoft.Azure.Management.ServiceBus library instead.如果您还需要能够创建命名空间,请改用Microsoft.Azure.Management.ServiceBus库。

  1. Receive and delete until there's no message接收和删除直到没有消息
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 is self-explanatory. ReceiveMode = ServiceBusReceiveMode.ReceiveAndDelete是不言自明的。 The default receive mode is PeekLock which doesn't actually remove messages from the queue - it tells Service Bus that the receiving client wants to settle the received messages explicitly.默认接收模式是PeekLock ,它实际上并不从队列中删除消息 - 它告诉服务总线接收客户端想要明确地解决接收到的消息。 The lock part means competing receivers can't access the message for the duration of the lock.锁定部分意味着竞争接收者在锁定期间无法访问消息。

  1. Use Queue Service REST API (not tested).使用队列服务 REST API(未测试)。

The Clear Messages operation deletes all messages from the specified queue Clear Messages 操作删除指定队列中的所有消息

DELETE https://myaccount.queue.core.windows.net/myqueue/messages删除https://myaccount.queue.core.windows.net/myqueue/messages

Only the account owner may call this operation.只有帐户所有者可以调用此操作。

PS.附言。 The URL seems to be wrong. URL 好像是错误的。 Try this instead: https://myaccount.servicebus.windows.net/myqueue/messages试试这个: https://myaccount.servicebus.windows.net/myqueue/messages

Source: https://learn.microsoft.com/en-us/rest/api/storageservices/clear-messages来源: https://learn.microsoft.com/en-us/rest/api/storageservices/clear-messages

Or...或者...

  1. Create a logic app to delete messages one by one in a loop (tested).创建一个逻辑应用程序以在循环中一条一条地删除消息(已测试)。

在此处输入图像描述

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM