2015-08-11 6 views
8

Mit einem Azure Service Bus arbeiten Problem, bei dem zurzeit ein Problem auftritt, bei dem meine Nachrichten mit der ReceiveBatch-Methode empfangen werden. Das Problem ist, dass die erwarteten Ergebnisse nicht wirklich die Ergebnisse sind, die ich bekomme. Hier ist die grundlegende Code-Setup, sind Anwendungsfälle unter:Ungerades Verhalten von Azure Service Bus ReceiveBatch()

SubscriptionClient client = SubscriptionClient.CreateFromConnectionString(connectionString, convoTopic, subName); 

    IEnumerable<BrokeredMessage> messageList = client.ReceiveBatch(100); 
     foreach (BrokeredMessage message in messageList) 
     { 
      try 
      { 
       Console.WriteLine(message.GetBody<string>() + message.MessageId); 

       message.Complete(); 
      } 
      catch (Exception ex) 
      { 
       message.Abandon(); 
      } 
     } 

    client.Close(); 
    MessageBox.Show("Done"); 
  1. den obigen Code verwenden, wenn ich 4-Nachrichten senden, dann auf dem ersten Lauf Umfrage durch ich die erste Meldung. Beim zweiten Durchlauf bekomme ich die anderen 3. Ich erwarte, alle 4 gleichzeitig zu bekommen. Es scheint immer einen singulären Wert bei der ersten Umfrage zurückzugeben, dann den Rest bei nachfolgenden Umfragen. (Das gleiche Ergebnis mit 3 und 5, wo ich n-1 von n Nachrichten beim zweiten Versuch und 1 Nachricht beim ersten Versuch erhalten).

  2. Wenn ich 0 Nachrichten empfangen habe, dauert die Operation zwischen ~ 30-60 Sekunden, um die messageList zu erhalten (die eine 0 zählt). Ich brauche das sofort zurückzukehren.

  3. Wenn ich den Code IEnumerable<BrokeredMessage> messageList = client.ReceiveBatch(100, new Timespan(0,0,0)); dann ausgeben ändern 2 # weggeht, weil issue 1 noch andauert, wo ich den Code zweimal anrufen müssen, um alle Nachrichten zu bekommen.

Ich gehe davon aus, dass die Ausgabe # 2 ist wegen eines Standard-Timeout-Wert, die ich in # überschreiben 3 (obwohl ich es finden verwirrend, dass, wenn eine Nachricht da ist es reagiert sofort, ohne den Standardwartezeit). Ich bin mir nicht sicher, warum ich nie die volle Anzahl an Nachrichten in einem einzigen ReceiveBatch bekomme.

+1

Gibt es zufällig "Thema" in Frage ist "Partitioniert"? Ich habe genau dasselbe Verhalten bei einer "Partitioned Queue" gesehen. –

+0

Danke, das war ein Teil des Problems. –

Antwort

6

Die Art, wie ich ReceiveBatch() erhielt, um richtig zu arbeiten, war, zwei Dinge zu tun.

  1. deaktivieren Partitionierung im Thema (ich hatte ein neues Thema für diese zu machen, weil Sie nicht, dass nach der Erstellung umschalten)
  2. aktivieren Dosiersysteme für jedes Abonnement erstellt wie folgt:
  3. Liste item

SubscriptionDescription sd = new SubscriptionDescription(topicName, orgSubName); sd.EnableBatchedOperations = true;

Nachdem ich diese beiden Dinge tat, ich war in der Lage, die Themen zu bekommen, wie beabsichtigt arbeiten mit IEnumerable<BrokeredMessage> messageList = client.ReceiveBatch(100, new TimeSpan(0,0,0));

0

Ich habe ein ähnliches Problem mit einer ASB-Warteschlange. Ich entdeckte, dass ich es etwas durch die Erhöhung der PrefetchCount auf dem Client die Charge vor dem Empfang mildern könnte:

SubscriptionClient client = SubscriptionClient.CreateFromConnectionString(connectionString, convoTopic, subName); 

client.PrefetchCount = 100; 

IEnumerable<BrokeredMessage> messageList = client.ReceiveBatch(100); 

Vom Azure Service Bus Best Practices for Performance Improvements Using Service Bus Brokered Messaging:

Prefetching die Warteschlange oder Abonnement-Client ermöglicht zu laden zusätzliche Nachrichten vom Dienst, wenn eine Empfangsoperation ausgeführt wird. Raten aller Empfänger der Fabrik

...

Wenn die Sperre Ablauf von 60 Sekunden standardmäßig verwendet wird, einen guten Wert für SubscriptionClient.PrefetchCount 20-mal die maximalen Verarbeitungs sind. Zum Beispiel erstellt eine Fabrik 3 Empfänger, und jeder Empfänger kann bis zu 10 Nachrichten pro Sekunde verarbeiten. Die Prefetch Zahl sollte nicht mehr als 20 * 3 * 10 = 600.

...

Prefetch-Nachrichten erhöht den Gesamtdurchsatz für eine Warteschlange oder ein Abonnement, weil es die Gesamtzahl der Nachrichtenoperationen oder Rundfahrten reduziert. Das Abrufen der ersten Nachricht dauert jedoch länger (aufgrund der erhöhten Nachrichtengröße). Prefetch-Nachrichten werden schneller empfangen, da diese Nachrichten bereits vom Client heruntergeladen wurden.

+0

Dies schien das Problem zu helfen, aber nicht vollständig zu lösen. Danke für den Versuch. –

0

Nur noch ein paar Stücke zum Puzzle. Ich konnte es auch nach dem Aktivieren von Batching und Disable Partitioning immer noch nicht zum Laufen bringen - ich musste noch zwei ReceiveBatch-Aufrufe machen. Ich habe jedoch gefunden:

  • Neustart der Service-Bus-Dienste (Ich benutze Service Bus für Windows Server) klärte das Problem für mich.
  • Wenn Sie einen einzigen RecieveBatch ausführen und keine Aktion ausführen (die Nachrichtensperren ablaufen lassen) und dann einen weiteren ReceiveBatch ausführen, werden alle Nachrichten gleichzeitig durchgestellt. (Ein initiales ReceiveBatch und der Aufruf von Abandon für alle Nachrichten führten nicht zu diesem Verhalten.)
  • Es scheint also eine Art von Korruption/Fehler in In-Memory-Cache von Service Bus.