2012-03-29 17 views
18

हम अपनी परियोजना में एक सेवा बस कतार का उपयोग कर रहे हैं। जब कतार को साफ़ करने का विकल्प चुनता है तो हमें कतार से सभी संदेशों को हटाने की कार्यक्षमता की आवश्यकता होती है। मैंने नेट पर खोज की लेकिन उसे कोई फंक्शन नहीं मिला जो QueueClient कक्षा के अंदर करता है।एक बार में एज़ूर सेवा बस कतार साफ़ करना

क्या मुझे सभी संदेशों को एक-एक करके पॉप करना होगा और फिर उन्हें कतार को साफ़ करने के लिए पूर्ण चिह्नित करना होगा या कोई बेहतर तरीका है?

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

BrokeredMessage brokeredMessage = queueClient.Receive(); 

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

मुझे हाल ही में एक ही समस्या का सामना करना पड़ा, और हटाना और पुनर्निर्माण एक विकल्प नहीं था, लूपिंग काम करता था, लेकिन धीमा है, हालांकि, 'क्यूई क्लाइंट' के 'प्रीफेटच काउंटी' सदस्य का उपयोग करके आप आसानी से एक हजार में कुछ हज़ार संदेश बैच कर सकते हैं राउंड-ट्रिप, तेजी से चीजों को तेज करना: http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.queueclient.prefetchcount.aspx – Necrolis

उत्तर

8

जबकि पाश के भीतर Receive() पद्धति का उपयोग करना है जैसे आप अपने कोड अनिश्चित काल तक चलाना एक बार कतार खाली है कारण होगा Receive() विधि कतार पर प्रकट करने के एक और संदेश के लिए इंतजार कर रहे होंगे के रूप में कर रहे हैं।

यदि आप इसे स्वचालित रूप से चलाने के लिए चाहते हैं, तो Peek() विधि का उपयोग करने का प्रयास करें।

उदाहरण के लिए:

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

आप ReceiveMode.ReceiveAndDelete के साथ इस फिर से आसान बनाने के कर सकते हैं के रूप में hocho द्वारा उल्लेख किया गया था।

+1

कुछ चिंताओं: (1) पीक को निर्धारित, भविष्य मिलेगा प्राप्त संदेश जो आपके ऐप को अनुसूचित संदेशों के लिए प्रतीक्षा करने का कारण नहीं देगा। (2) प्रत्येक peek अगले स्थिति में इसकी स्थिति के बावजूद आगे बढ़ता है, इसलिए यदि आप पूर्ण करने के बजाय पहले संदेश को छोड़ देते हैं, तो दूसरी पिक को दूसरा संदेश मिलेगा लेकिन दूसरा प्राप्तकर्ता 1 को पुन: संसाधित करेगा। इससे पीक को एक संदेश से प्राप्त होने से ऑफसेट किया जा सकता है और प्रत्येक त्याग किए गए संदेश के लिए आपकी कतार के अंत में एक संदेश अनप्रचारित छोड़ दिया जाएगा। –

+0

+1 @ जस्टिन जेस्टर्क इस संदेश का परीक्षण करते समय (जैसा कि, कोई प्रसंस्करण नहीं है, बस प्राप्त करें और पूर्ण करें) एक कतार के खिलाफ जो नए संदेश प्राप्त नहीं कर रहा था, यह हमेशा कतार को पूरी तरह से साफ़ करने में असफल रहा। यह केवल 50-75% संदेशों को साफ़ कर रहा था। मैं एक कतार को साफ़ करने के लिए इस दृष्टिकोण का उपयोग नहीं करता। – Justin

2

Azure-ServiceBus-Queues के लिए ReceiveBatch-method है जो आपको उस समय n -messages का बैच प्राप्त करने की अनुमति देता है। ReceiveMode.ReceiveAndDelete के साथ संयुक्त आप कतार को और अधिक कुशलता से साफ़ कर सकते हैं।

चेतावनी संख्या n संदेशों के लिए वापस आ रहा हो सकता है, लेकिन यह गारंटी नहीं है। 256K के संदेश-बैच आकार के लिए भी एक सीमा है।

5

का उपयोग करना:

  • दोनों दृष्टिकोण (@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); 
} 
1

Azure Serv को साफ़ करने का सबसे तेज़ तरीका IceBus Queue एक बहुत छोटा 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; 
+0

हाय फ्लोरंट, सुनिश्चित नहीं है कि एपीआई बदल गई है, लेकिन मैंने बस अपनी कतार पर यह कोशिश की और इसमें शून्य बदलाव हुए। पहले और बाद में कतार में वही संदेश। –

0

एक सरल Clear() अगर आप nuget से WindowsAzure.Storage पुस्तकालय का उपयोग कर रहे पूरे कतार खाली करने के लिए तरीका है। मैं कतार का प्रबंधन करने के लिए उस लाइब्रेरी से Microsoft.Windows.Azure.Queue कक्षा का उपयोग करता हूं। अन्यथा, आप उनके एपीआई per their documentation के माध्यम से उपयोग कर सकते हैं। मुझे नहीं पता कि एज़ूर लाइब्रेरी में विधि कितनी देर तक चल रही है और जब संभवतः सवाल पूछा गया था, तो यह संभवतः अस्तित्व में नहीं था, लेकिन आरईएसटी एपीआई कम से कम 2014 प्रति this Azure feedback post

पूर्ण हो गया है।Azure पुस्तकालय के साथ कतार खाली करने के लिए नेट कोड है:

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

मैं ReceiveAndDelete, PrefetchCount, ReceiveBatchAsync का एक संयोजन है, और एक साधारण सच पाश का उपयोग कर अच्छे परिणाम हो रही है बजाय पीक का उपयोग कर। नीचे 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 पैकेज की आवश्यकता है।

संबंधित मुद्दे