2015-08-11 23 views
8

Utilizzo di un argomento del bus di servizio di Azure al momento e in esecuzione in un problema durante la ricezione dei messaggi mediante il metodo ReceiveBatch. Il problema è che i risultati attesi non sono in realtà i risultati che sto ottenendo. Ecco l'impostazione del codice di base, casi d'uso sono al di sotto:Comportamento dispari del servizio di ricezione di Azure 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. Utilizzando il codice di cui sopra, se mando 4 messaggi, quindi il polling sulla prima esecuzione attraverso ottengo il primo messaggio. Alla seconda manche ho l'altro 3. Mi aspetto di ottenere tutti e 4 allo stesso tempo. Sembra sempre restituire un valore singolare sul primo sondaggio e il resto sui sondaggi successivi. (stesso risultato con 3 e 5 dove ottengo n-1 di n messaggi inviati al secondo tentativo e 1 messaggio al primo tentativo).

  2. Se ho 0 messaggi da ricevere, l'operazione richiede tra ~ 30-60 secondi per ottenere l'elenco dei messaggi (che ha un conteggio 0). Ho bisogno di questo per tornare all'istante.

  3. Se cambio il codice in IEnumerable<BrokeredMessage> messageList = client.ReceiveBatch(100, new Timespan(0,0,0));, il numero 2 scompare perché il problema 1 persiste ancora dove devo chiamare il codice due volte per ottenere tutti i messaggi.

sto supponendo che l'edizione # 2 è a causa di un valore di timeout predefinito che ho sovrascrivere a # 3 (anche se mi trovo confuso che se un messaggio è lì risponde immediatamente senza attendere il tempo di default). Non sono sicuro del motivo per cui non ricevo mai l'intera quantità di messaggi in una sola ReceiveBatch.

+1

È possibile che "Argomento" in questione sia "Partizionato"? Ho visto esattamente lo stesso comportamento con una 'Partitioned Queue'. –

+0

Grazie, questo era parte del problema. –

risposta

6

Il modo in cui ReceiveBatch() funzionava correttamente era di fare due cose.

  1. disattivare il partizionamento nella Topic (ho dovuto fare un nuovo argomento per questo, perché non è possibile passare che dopo la creazione)
  2. Abilita raggruppamento su ogni abbonamento creato in questo modo:
  3. voce dell'Elenco

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

Dopo che ho fatto queste due cose, sono stato in grado di ottenere gli argomenti per funzionare come previsto utilizzando IEnumerable<BrokeredMessage> messageList = client.ReceiveBatch(100, new TimeSpan(0,0,0));

0

Sto riscontrando un problema simile con una coda ASB. Ho scoperto che avrei potuto mitigare in qualche modo, aumentando la PrefetchCount sul client prima di ricevere il lotto:

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

client.PrefetchCount = 100; 

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

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

Prefetching consente al client coda o di sottoscrizione per caricare messaggi aggiuntivi dal servizio quando esegue un'operazione di ricezione.

...

Quando si utilizza la scadenza di blocco predefinito di 60 secondi, un buon rapporto qualità- SubscriptionClient.PrefetchCount è 20 volte i tassi massimi di trasformazione di tutti i ricevitori della fabbrica. Ad esempio, una fabbrica crea 3 ricevitori e ciascun ricevitore può elaborare fino a 10 messaggi al secondo. Il conteggio prefetch non deve superare i 20 * 3 * 10 = 600.

...

messaggi prefetching aumenta il throughput complessivo per una coda o un abbonamento, perché riduce il numero complessivo delle operazioni dei messaggi, o di andata e ritorno. Il recupero del primo messaggio, tuttavia, richiederà più tempo (a causa della maggiore dimensione del messaggio). La ricezione di messaggi precaricati sarà più veloce perché questi messaggi sono già stati scaricati dal client.

+0

Questo sembrava aiutare il problema, ma non risolverlo completamente. Grazie per aver tentato. –

0

Solo pochi pezzi del puzzle. Ancora non riuscivo a farlo funzionare anche dopo Enable Batching e Disable Partitioning - dovevo ancora fare due chiamate ReceiveBatch. Tuttavia, ho trovato:

  • Il riavvio dei servizi del bus di servizio (sto utilizzando il bus di servizio per Windows Server) ha risolto il problema per me.
  • Eseguire un singolo RecieveBatch e non eseguire alcuna azione (lasciando scadere il blocco dei messaggi) e quindi eseguire un altro ReceiveBatch ha causato l'interconnessione di tutti i messaggi allo stesso tempo. (Fare un ReceiveBatch iniziale e chiamare Abandon su tutti i messaggi non ha causato quel comportamento.)

Quindi sembra essere una sorta di corruzione/bug nella cache di memoria del bus di servizio.

Problemi correlati