2012-03-29 4 views
18

우리 프로젝트에서 서비스 버스 대기열을 사용하고 있습니다. 관리자가 큐를 지우도록 선택하면 큐에서 모든 메시지를 제거하는 기능이 필요합니다. 그물을 검색했지만 QueueClient 클래스 안에서이 작업을 수행하는 기능을 찾을 수 없습니다.한 번에 하늘빛 서비스 버스 대기열 지우기

모든 메시지를 하나씩 팝핑 한 다음 큐를 지우려면 완료 표시를해야합니까? 아니면 더 좋은 방법이 있습니까? 당신이 Receive() 방법은 큐에 나타나는 다른 메시지 기다리고있을 것 같은, 큐가 비어되면 코드가 무기한 실행하게됩니다처럼 while 루프 내에서 Receive() 방법을 사용하여

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

BrokeredMessage brokeredMessage = queueClient.Receive(); 

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

나는 최근에 똑같은 문제에 직면했다. 삭제와 재생성은 옵션이 아니었지만 반복적으로 작동하지만 느리다. 그러나 'QueueClient'의'PrefetchCount' 멤버를 사용하면 단 하나의 메시지로 수천 개의 메시지를 쉽게 배치 할 수있다. 왕복 여행으로 엄청난 속도를 낼 수 있습니다. http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.queueclient.prefetchcount.aspx – Necrolis

답변

8

.

자동으로 실행하려면 Peek() 메서드를 사용해보십시오. 예를 들어

: hocho 언급 한대로이 ReceiveMode.ReceiveAndDelete으로이 간단 다시 만들 수 있습니다

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

.

+1

몇 가지 우려 사항 : (1) 픽은 앞으로 예정되어 있으며, 앞으로 수신 메시지는 귀하의 앱이 예정된 메시지를 기다리는 것을 멈추게합니다. (2) 각 Peek은 상태에 관계없이 다음 메시지로 이동하므로 완료 대신 첫 번째 메시지를 포기하면 두 번째 픽에는 두 번째 메시지가 표시되지만 두 번째 수신은 첫 번째 메시지를 다시 처리합니다. 이로 인해 Peek는 하나의 메시지로 수신에서 오프셋되고 각 메시지에 대해 대기열 끝에 하나의 메시지가 처리되지 않게됩니다. –

+0

+1 @JustinJStark 새 메시지를 수신하지 못하는 큐에 대해이 코드를 테스트 할 때 (처리 없음, 수신 및 완료), 항상 큐를 완전히 지우지 못했습니다. 메시지의 50-75 % 만 지우고있었습니다. 큐를 지우려면이 방법을 사용하지 않을 것입니다. – Justin

2

Azure-ServiceBus 대기열의 경우 n - 메시지를 수신 할 수있는 ReceiveBatch-method이 있습니다. 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

가장 빠른 방법은 푸른 SERV를 청소 iceBus 대기열은 매우 짧은 DefaultMessageTimeToLive을 설정하고 몇 초 기다렸다가 강제로 대기열에서 수신을 시도한 다음 초기화하여 DefaultMessageTimeToLive을 복원합니다.

당신은 포털에서 또는 코드에서 그것을 할 수 있습니다 : 당신이 nuget에서 WindowsAzure.Storage 라이브러리를 사용하는 경우 전체 큐를 취소하는 간단한 Clear() 방법이있다

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

Hi Florent, API가 변경된 것인지 확실하지 않지만 방금 내 대기열에서 시도했지만 변경 사항이 없습니다. 앞뒤에 같은 메시지가 대기열에 있습니다. –

0

. 해당 라이브러리의 Microsoft.Windows.Azure.Queue 클래스를 사용하여 큐를 관리합니다. 그렇지 않은 경우 API per their documentation을 통해 액세스 할 수 있습니다. Azure 라이브러리에있는 메소드가 얼마나 오래 있었는지는 모르지만 질문이 원래 요청되었을 때 존재하지 않았지만 REST API는 적어도 2014 년 이후에 다시 발생합니다. this Azure feedback post

전체가 채워집니다.애저 라이브러리 큐를 취소 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(); 
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 패키지가 필요합니다.

관련 문제