2015-08-11 23 views
8

Praca z tematem usługi Azure Service Bus, który obecnie jest uruchomiony i pojawia się problem z odebraniem moich wiadomości za pomocą metody ReceiveBatch. Problem polega na tym, że oczekiwane wyniki nie są tak naprawdę rezultatami, które otrzymuję. Oto podstawowa konfiguracja kod, przypadki użycia są poniżej:Dziwne zachowanie usługi 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. Stosując powyższy kod, jeśli wyślę 4 wiadomości, a następnie sondować na pierwszym biegu przez uzyskać pierwszą wiadomość. Przy drugim przejściu dostaję drugie 3. Spodziewam się, że wszystkie 4 będą w tym samym czasie. Wydaje się, że zawsze zwraca pojedynczą wartość w pierwszej ankiecie, a resztę w kolejnych ankietach. (ten sam wynik z 3 i 5, gdzie otrzymuję n-1 z n wiadomości wysłanych przy drugiej próbie i 1 wiadomości przy pierwszej próbie).

  2. Jeśli mam 0 wiadomości do odebrania, operacja zajmuje od ~ 30-60 sekund, aby uzyskać listę komunikatów (mającą liczbę 0). Potrzebuję tego, aby natychmiast powrócić.

  3. Jeśli zmienię kod na IEnumerable<BrokeredMessage> messageList = client.ReceiveBatch(100, new Timespan(0,0,0));, wydaję # 2, ponieważ problem 1 nadal występuje, gdy muszę wywołać kod dwukrotnie, aby uzyskać wszystkie wiadomości.

Zakładam, że problem # 2 z powodu domyślnej wartości limitu czasu, który mogę nadpisać w # 3 (chociaż uważam, że to dziwne, że jeśli wiadomość jest tam natychmiast reaguje bez czekania domyślny czas). Nie jestem pewien, dlaczego nigdy nie otrzymuję pełnej ilości wiadomości w jednym Odbiorniku.

+1

Czy istnieje szansa, że ​​"Tematem" jest "Partycjonowanie"? Widziałem dokładnie takie samo zachowanie z 'Partitioned Queue'. –

+0

Dzięki, to była część problemu. –

Odpowiedz

6

Sposób, w jaki otrzymałem funkcję ReceiveBatch() do prawidłowego działania, to wykonanie dwóch czynności.

  1. Wyłącz Partycjonowanie w temacie (musiałem zrobić nowy wątek o tym, ponieważ nie można przełączać się, że po stworzeniu)
  2. Włącz Składowanie na każdej subskrypcji utworzonej tak:
  3. przedmiot

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

Po zrobiłem te dwie rzeczy, udało mi się dostać tematy do pracy zgodnie z przeznaczeniem użyciu IEnumerable<BrokeredMessage> messageList = client.ReceiveBatch(100, new TimeSpan(0,0,0));

0

Mam podobny problem z kolejką ASB. Odkryłem, że mogę go złagodzić nieco zwiększając PrefetchCount na kliencie przed otrzymaniem serii:

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

client.PrefetchCount = 100; 

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

z magistrali Azure Usługa Best Practices for Performance Improvements Using Service Bus Brokered Messaging:

Wstępne pobieranie umożliwia kolejki lub subskrypcji klienta, aby załadować dodatkowe wiadomości z usługi, gdy wykonuje operację odbierania.

...

Przy użyciu domyślnej blokady upływie 60 sekund, dobry stosunek jakości do SubscriptionClient.PrefetchCount jest 20 razy maksymalne stawki przetwarzania wszystkich odbiorników fabryki. Na przykład fabryka tworzy 3 odbiorniki, a każdy odbiornik może przetwarzać do 10 wiadomości na sekundę. Ilość preselekcji nie powinna przekraczać 20 * 3 * 10 = 600.

...

wiadomości prefetching zwiększa całkowitą przepustowość kolejki lub subskrypcji, ponieważ zmniejsza ogólną liczbę operacji wiadomości lub rejsów. Pobieranie pierwszej wiadomości potrwa jednak dłużej (ze względu na zwiększony rozmiar wiadomości). Odbieranie wiadomości z wyprzedzeniem będzie szybsze, ponieważ te wiadomości zostały już pobrane przez klienta.

+0

Wydawało się, że to pomaga, ale nie rozwiązuje go całkowicie. Dzięki za próbę. –

0

Jeszcze tylko kilka elementów układanki. Nadal nie mogłem go uruchomić nawet po włączeniu opcji grupowania i wyłączania partycji - nadal musiałem wykonywać dwie wywołania funkcji Odbieranie wsadowe. Jednak znalazłem:

  • Ponowne uruchomienie usług magistrali usług (używam magistrali usług dla systemu Windows Server) wyjaśnił mi problem.
  • Wykonanie pojedynczej partii odbiorczej i niepodejmowanie żadnych działań (zezwolenie na blokadę wiadomości wygasa), a następnie wykonanie kolejnej funkcji Odbioruj powoduje, że wszystkie wiadomości przychodzą w tym samym czasie. (Wykonywanie początkowego ReceiveBatch i wywoływanie Opuszczenie wszystkich wiadomości nie spowodowało takiego zachowania.)

Wygląda więc na jakiś rodzaj korupcji/błędu w pamięci podręcznej magistrali usług.