2012-03-29 5 views
18

Nous utilisons une file d'attente de bus de service dans notre projet. Nous avons besoin d'une fonctionnalité pour supprimer tous les messages de la file d'attente lorsque l'administrateur choisit d'effacer la file d'attente. J'ai cherché sur le net mais je n'ai trouvé aucune fonction qui le fasse dans la classe QueueClient.Effacement d'une file d'attente de bus de service azure en une fois

Dois-je faire apparaître tous les messages un par un et les marquer pour terminer la file d'attente ou y a-t-il une meilleure solution?

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

BrokeredMessage brokeredMessage = queueClient.Receive(); 

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

J'ai récemment fait face au même problème, et la suppression et la recréation n'étaient pas une option, la boucle fonctionne, mais est lente, cependant, en utilisant le membre 'PrefetchCount' de' QueueClient' vous pouvez facilement traiter quelques milliers de messages en un seul aller-retour, accélérer les choses énormément: http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.queueclient.prefetchcount.aspx – Necrolis

Répondre

8

En utilisant la méthode Receive() dans la boucle while comme vous causera votre code à exécuter indéfiniment une fois que la file d'attente est vide, la méthode Receive() attendra un autre message à apparaître sur la file d'attente.

Si vous voulez que cela fonctionne automatiquement, essayez d'utiliser la méthode Peek().

Par exemple:

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

Vous pouvez vous simplifier la tâche à nouveau avec le ReceiveMode.ReceiveAndDelete comme cela a été mentionné par hocho.

+1

Quelques préoccupations: (1) Peek sera programmé, futur les messages qui reçoivent ne seront pas ce qui entraînera votre application à se bloquer en attente de messages planifiés. (2) Chaque Peek passe au message suivant quel que soit son statut, donc si vous Abandonnez le premier message au lieu de Terminé, le 2ème Peek recevra le 2ème message mais le 2ème Recevoir retraitera le 1er. Cela provoque Peek être décalé de recevoir par un message et laissera un message non traité à la fin de votre file d'attente pour chaque message abandonné. –

+0

+1 @JustinJStark Lors du test de ce code (tel quel, pas de traitement, il suffit de le recevoir et de le terminer) dans une file d'attente qui ne recevait pas de nouveaux messages, la file d'attente n'était jamais complètement effacée. Il nettoyait seulement 50-75% des messages. Je n'utiliserais pas cette approche pour effacer une file d'attente. – Justin

2

Pour Azure-ServiceBus-Files d'attente, il existe un ReceiveBatch-method qui vous permet de recevoir un lot de n -messages à la fois. Combiné avec ReceiveMode.ReceiveAndDelete vous pouvez effacer la file d'attente plus efficacement.

caveat Le nombre n de messages peut être retourné, mais ce n'est pas garanti. Il existe également une limite pour la taille de lot de messages de 256K.

5

utilisant:

  • approche à la fois (de @ScottBrady et @participant)
  • Et MessageReceiver abstraction

vous pouvez écrire une méthode qui vide une file d'attente de bus de service ou un sujet/abonnement:

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

Le moyen le plus rapide de nettoyer un serveur Azure iceBus Queue est de définir un très court DefaultMessageTimeToLive, attendez quelques secondes, essayez de recevoir de la file d'attente de la forcer à mettre à jour puis restaurer le DefaultMessageTimeToLive initial.

Vous pouvez le faire à partir du portail ou de 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; 
+0

Salut Florent, Je ne sais pas si l'API a changé, mais je l'ai juste essayé sur ma file d'attente et il n'y avait aucun changement. Mêmes messages dans la file d'attente avant et après. –

0

Il y a une méthode simple Clear() pour effacer toute la file d'attente si vous utilisez la bibliothèque WindowsAzure.Storage de NuGet. J'utilise la classe Microsoft.Windows.Azure.Queue de cette bibliothèque pour gérer la file d'attente. Sinon, vous pouvez accéder via leur API per their documentation. Je ne sais pas combien de temps la méthode a été dans la bibliothèque Azure et il n'existait probablement pas lorsque la question a été posée à l'origine, mais l'API REST remonte à au moins 2014 par this Azure feedback post

Le plein.Code NET pour effacer la file d'attente avec la bibliothèque Azure est:

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

Je vais avoir de bons résultats en utilisant une combinaison de ReceiveAndDelete, PrefetchCount, ReceiveBatchAsync et simple boucle de vérité plutôt que d'utiliser Peek. Exemple avec MessagingFactory ci-dessous:

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

ne nécessite que le paquet Nuget WindowsAzure.ServiceBus.

Questions connexes