.net 一次性清除 Azure 服务总线队列

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9920323/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 16:20:23  来源:igfitidea点击:

Clearing azure service bus queue in one go

.netazurequeueazureservicebusazure-servicebus-queues

提问by bhavesh lad

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 QueueClientclass.

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

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

回答by Scott Brady

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.

Receive()像您一样在 while 循环中使用该方法将导致您的代码在队列为空后无限期运行,因为该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.ReceiveAndDeleteas was mentioned by hocho.

您可以使用ReceiveMode.ReceiveAndDeletehocho 提到的使这再次变得更简单。

回答by Thomas

Using :

使用 :

  • Both approach (from @ScottBrady and @participant)
  • And the MessageReceiverabstraction
  • 两种方法(来自@ScottBrady 和@participant)
  • 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);
}

回答by ElliotSchmelliot

I'm having good results using a combination of ReceiveAndDelete, PrefetchCount, ReceiveBatchAsync, and a simple truth loop rather than using Peek. Example with MessagingFactory below:

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

Only requires the WindowsAzure.ServiceBusNuget package.

仅需要WindowsAzure.ServiceBusNuget 包。

回答by Florent Quienne

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 队列的最快方法是设置一个非常短DefaultMessageTimeToLiveDefaultMessageTimeToLive.

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;

回答by participant

For Azure-ServiceBus-Queues there is a ReceiveBatch-methodwhich allows you to receive a batch of n-messages at the time. Combined with ReceiveMode.ReceiveAndDeleteyou can clear the queue more efficiently.

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

CaveatThe number nof messages might be returned but it's not guaranteed. Also there is a limit for the message-batch size of 256K.

买者数量ň的消息可能会返回,但它不能保证。消息批量大小也有限制256K

回答by jozolo

There is a simple Clear()method to clear the entire queue if you are using the WindowsAzure.Storage library from nuget. I use the Microsoft.Windows.Azure.Queueclass from that library to manage the queue. Otherwise, you can access via their API per their documentation. 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

Clear()如果您使用 nuget 中的 WindowsAzure.Storage 库,则有一种简单的方法可以清除整个队列。我使用该Microsoft.Windows.Azure.Queue库中的类来管理队列。否则,您可以根据他们的文档通过他们的 API 进行访问。我不知道该方法在 Azure 库中存在多久了,最初提出问题时它可能不存在,但根据Azure 反馈帖子,REST API 至少可以追溯到 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();