2015-02-19 4 views
5

cerco di accodare i messaggi in Azure code in modo asincrono in questo modo:asincrono intervento a Azure code

private async Task EnqueueItemsAsync(IEnumerable<string> messages) { 
      var tasks = messages.Select(msg => _queue.AddMessageAsync(new CloudQueueMessage(msg), 
       null, null, null, null)); 

      await Task.WhenAll(tasks); 
     } 

Se ho capito bene questo dice "avviare l'accodamento un elemento dopo l'altro senza di loro per ottenere pubblicato in attesa, tenere un riferimento per ogni attività e quindi attendere che tutti vengano pubblicati ".

Questo codice funziona bene nella maggior parte dei casi, ma per un gran numero di articoli (5000), inizia l'accodamento e poi genera un'eccezione timeout (dopo aver accodato ~ 3500 articoli).

ho risolto aspettando ognuno di finire prima di continuare con il successivo

private async Task EnqueueItemsAsync(IEnumerable<string> messages) { 
      foreach (var message in messages) { 
       await _queue.AddMessageAsync(new CloudQueueMessage(message), null, null, null, null); 
      } 
     } 

Qualcuno può spiegare perché questo è accaduto?

Eccezione:

System.AggregateException che avvolge molte di queste eccezioni: Microsoft.WindowsAzure.Storage.Core.Util.AsyncExtensions.<>c__DisplayClass4.<CreateCallbackVoid>b__3(IAsyncResult ar) Richiesta Informazioni IDRichiesta: RequestDate: StatusMessage: < --- ---> (Eccezione interna # 1) Microsoft.WindowsAzure.Storage. StorageException: il client non ha potuto terminare l'operazione entro il timeout specificato. ---> System.TimeoutException: il client non ha potuto completare l'operazione entro il timeout specificato. --- Fine della traccia dello stack di eccezioni interne --- Microsoft.WindowsAzure.Storage.Core.Executor.Executor.EndExecuteAsync [T] (IAsyncResult risultato) `.

+0

Quale linea genera l'eccezione? e quale metodo? Pubblica il nome dell'eccezione, il messaggio e lo stacktrace –

+0

@SriramSakthivel grazie per averlo menzionato, ho appena aggiornato il mio post –

risposta

6

Si progetta una coda in Azure con un volume di 2000 messaggi al secondo.

See: Azure Storage Scalability and Performance Targets

Quando l'applicazione raggiunge il limite di ciò che una partizione in grado di gestire per il carico di lavoro, Azure inizierà a restituire il codice di errore 503 codice (Server occupato) o errore 500 (Operation Timeout) risposte. In questo caso, l'applicazione deve utilizzare un criterio di backoff esponenziale per i tentativi. Il backoff esponenziale consente di ridurre il carico sulla partizione e di ridurre i picchi di traffico verso quella partizione.

+0

Grazie, credo che questo risolva l'enigma. Quindi il mio primo codice esegue il ciclo for in meno di un secondo, iniziando 5000 richieste di posta in meno di un secondo che risultano risposte di timeout ... sembra ragionevole –

1

Sembra che sia possibile rendere un meccanismo più affidabile passando un QueryRequestOptions a AddMessageAsync.

Prima che la query venga inviata, il messaggio di richiesta aggiunge queste proprietà al comando.

Vorrei provare a passare QueryRequestOptions e impostare un valore su MaximumExecutionTime e ServerTimeout con un valore maggiore.

Questo è come la richiesta viene riempito prima di essere inviato:

// Microsoft.WindowsAzure.Storage.Queue.QueueRequestOptions 
internal void ApplyToStorageCommand<T>(RESTCommand<T> cmd) 
{ 
    if (this.LocationMode.HasValue) 
    { 
     cmd.LocationMode = this.LocationMode.Value; 
    } 
    if (this.ServerTimeout.HasValue) 
    { 
     cmd.ServerTimeoutInSeconds = new int?((int)this.ServerTimeout.Value.TotalSeconds); 
    } 
    if (this.OperationExpiryTime.HasValue) 
    { 
     cmd.OperationExpiryTime = this.OperationExpiryTime; 
     return; 
    } 
    if (this.MaximumExecutionTime.HasValue) 
    { 
     cmd.OperationExpiryTime = new DateTime?(DateTime.Now + this.MaximumExecutionTime.Value); 
    } 
} 

e questo è come è inviato:

rESTCommand.PreProcessResponse = delegate(RESTCommand<NullType> cmd, HttpWebResponse resp, Exception ex, OperationContext ctx) 
{ 
    HttpResponseParsers.ProcessExpectedStatusCodeNoException<NullType>(HttpStatusCode.Created, resp, NullType.Value, cmd, ex); 
    return NullType.Value; 
}; 
+0

Grazie, approccio interessante per minimizzare la possibilità di un timeout, tuttavia volevo capire cosa ha causato il timeout in primo luogo. –