2015-11-27 2 views
7

Stiamo utilizzando il seguente metodo in un servizio Stateful su Service-Fabric. Il servizio ha partizioni. A volte otteniamo un'eccezione FabricNotReadable da questa pace di codice.Che cosa significa FabricNotReadableException? E come dovremmo rispondere ad esso?

public async Task HandleEvent(EventHandlerMessage message) 
{ 
    var queue = await StateManager.GetOrAddAsync<IReliableQueue<EventHandlerMessage>>(EventHandlerServiceConstants.EventHandlerQueueName); 
    using(ITransaction tx = StateManager.CreateTransaction()) 
    { 
     await queue.EnqueueAsync(tx, message); 
     await tx.CommitAsync(); 
    } 
} 

Ciò significa che la partizione è inattiva e viene spostata? Di quello colpiamo una partizione secondaria? Perché c'è anche una FabricNotPrimaryException che viene sollevata in alcuni casi.

Ho visto il collegamento MSDN (https://msdn.microsoft.com/en-us/library/azure/system.fabric.fabricnotreadableexception.aspx). Ma cosa significa

Rappresenta un'eccezione generata quando una partizione non può accettare le letture.

significa? Che cosa è successo che una partizione non può accettare una lettura?

+0

https://msdn.microsoft.com/en-us/library/azure/system.fabric.fabricnotreadableexception.aspx Google è tuo amico su questo – TheLethalCoder

+1

@ TheLethalCoder che non lo rende più chiaro :( –

risposta

10

Sotto le coperte, Service Fabric ha diversi stati che possono influire sul fatto che una determinata replica possa servire in modo sicuro letture e scritture. Essi sono:

  • Assegnato (si può pensare a questo come il normale funzionamento)
  • Non primario
  • No Write Quorum (di nuovo scrive che incidono principalmente)
  • Riconfigurazione attesa

FabricNotPrimaryException che si menziona può essere lanciato ogni volta che si tenta una scrittura su una replica che non è al momento il Primario e si associa allo stato NotPrimary.

FabricNotReadableException esegue il mapping agli altri stati (non è necessario preoccuparsi o differenziarli tra loro) e può verificarsi in una varietà di casi. Un esempio è se la replica su cui si sta tentando di eseguire la lettura è una replica "Standby" (una replica che era inattiva e che è stata ripristinata, ma esistono già abbastanza repliche attive nel set di repliche). Un altro esempio è se la replica è una Primaria ma viene chiusa (ad esempio a causa di un aggiornamento o perché ha segnalato un errore) o se è attualmente in fase di riconfigurazione (ad esempio, si sta aggiungendo un'altra replica). Tutte queste condizioni determinano il fatto che la replica non è in grado di soddisfare le scritture per un breve periodo di tempo a causa di alcuni controlli di sicurezza e modifiche atomiche che Service Fabric deve gestire sotto il cofano.

È possibile considerare FabricNotReadableException retraibile. Se lo vedi, prova di nuovo la chiamata e alla fine si risolverà in NotPrimary o Grant. Se si ottiene un'eccezione FabricNotPrimary, generalmente questa deve essere restituita al client (o al client in qualche modo notificato) che deve essere risolta per trovare il Primary corrente (gli stack di comunicazione predefiniti che Service Fabric invierà guardando per le eccezioni non recuperabili e ri-risoluzione per tuo conto).

Esistono due problemi noti correnti con FabricNotReadableException.

  1. FabricNotReadableException dovrebbe avere due varianti. Il primo dovrebbe essere esplicitamente retribuito (FabricTransientNotReadableException) e il secondo dovrebbe essere FabricNotReadableException. La prima versione (Transient) è la più comune ed è probabilmente quello che stai incontrando, sicuramente quello che ti interesserebbe nella maggior parte dei casi. Il secondo (non transitorio) verrebbe restituito nel caso in cui si finisca per parlare con una replica di standby.Parlare in standby non accadrà con il trasporto in partenza e riprovare la logica, ma se hai il tuo, è possibile imbattersi in esso.
  2. L'altro problema è che oggi FabricNotReadableException dovrebbe derivare da FabricTransientException, rendendo più facile determinare quale sia il comportamento corretto.
+0

Matt, sembra (sul mio cluster di sviluppo), sto colpendo questa eccezione costantemente per il mio servizio affidabile stateful. Sto accedendo al seguente metodo: StateManager.GetOrAddAsync > ("name") nel mio CommunicationListener e ottengo costantemente FabricNotReadableException ... Qualche idea su come risolverlo? –

+0

Probabilmente è perché sono troppo presto nel ciclo di vita del mio servizio. Sto eseguendo il metodo GetOrAddAsync in OpenAsync del mio listener di comunicazione, dove ottengo l'eccezione. Se lo faccio in RunAsync, le cose funzionano. La domanda ora è: come posso accedere a ReliableCollections in un elenco di comunicazione in modo sicuro? –

+0

OpenAsync dovrebbe solo stabilire l'ascoltatore e quindi completare - il servizio non è leggibile/scrivibile in quel momento. L'aspettativa è che le richieste arrivino più tardi (all'indirizzo restituito da Open) a quel punto vengono gestite. Non iniziamo RunAsync finché la replica non è leggibile, motivo per cui non vedi l'errore lì. – masnider

1

Inserito come risposta (al commento di asnider - 16 marzo alle 17:42) perché era troppo lungo per i commenti! :)

Sono bloccato anche in questa cattura 22. Il mio svc inizia e riceve immediatamente i messaggi. Voglio incapsulare l'avvio del servizio in OpenAsync e impostare alcuni valori ReliableDictionary, quindi iniziare a ricevere il messaggio. Tuttavia, a questo punto, il tessuto non è leggibile e ho bisogno di dividere questo "startup" tra openAsync e RunAsync :(

RunAsync nel mio servizio e OpenAsync nel mio client sembrano anche avere diversi gettoni di annullamento, quindi ho bisogno di lavoro su come affrontare anche questo.Esso tutto sembra un po 'disordinato.Ho un numero di idee su come riordinare questo nel mio codice ma qualcuno ha trovato una soluzione elegante?

Sarebbe bello se ICommunicationClient aveva un'interfaccia RunAsync chiamata quando il Fabric è pronto/leggibile e cancellato quando Fabric arresta la replica - questo mi semplificerebbe seriamente la vita. :)

+1

Capito, ma sfortunatamente è sempre una gara poiché lo stato di lettura/scrittura può essere portato via in qualsiasi momento. Quindi anche l'API è stata chiamata solo quando le cose erano pronte, nel momento in cui il servizio ha effettivamente risposto, lo stato di scrittura potrebbe essere diverso. Generalmente le persone dovrebbero solo iniziare a gestire le richieste e fallire se la configurazione non è completa per qualche motivo e fare affidamento sui tentativi del client. – masnider

+0

Alla fine ho usato Polly e qualche astrazione per renderlo affidabile (scusate il gioco di parole). https://github.com/App-vNext/Polly –