Ciclo di vita di Reliable ServicesReliable Services lifecycle

Reliable Services è uno dei modelli di programmazione disponibili in Azure Service Fabric.Reliable Services is one of the programming models available in Azure Service Fabric. Quando si parla del ciclo di vita di Reliable Services, è estremamente importante comprendere gli eventi di base del ciclo di vita.When learning about the lifecycle of Reliable Services, it's most important to understand the basic lifecycle events. L'ordine esatto degli eventi dipende dai dettagli di configurazione.The exact ordering of events depends on configuration details.

In generale, il ciclo di vita di Reliable Services include gli eventi seguenti:In general, the Reliable Services lifecycle includes the following events:

  • Durante l'avvio:During startup:
    • I servizi vengono costruiti.Services are constructed.
    • I servizi hanno la possibilità di costruire e restituire zero o più listener.Services have an opportunity to construct and return zero or more listeners.
    • Qualsiasi listener restituito viene aperto per la comunicazione con il servizio.Any returned listeners are opened, for communication with the service.
    • Viene chiamato il metodo runAsync del servizio, in modo che il servizio stesso possa eseguire operazioni a esecuzione prolungata o in background.The service's runAsync method is called, so the service can do long-running or background work.
  • Durante l'arresto:During shutdown:
    • Il token di annullamento che è stato passato a runAsync viene annullato e i listener vengono chiusi.The cancellation token that was passed to runAsync is canceled, and the listeners are closed.
    • L'oggetto servizio stesso viene eliminato.The service object itself is destructed.

L'ordine degli eventi in Reliable Services potrebbe cambiare leggermente a seconda che il servizio Reliable sia con o senza stato.The order of events in Reliable Services might change slightly depending on whether the reliable service is stateless or stateful.

Inoltre, per i servizi con stato, è necessario gestire lo scenario di scambio del ruolo primario.Also, for stateful services, you must address the primary swap scenario. Durante questa sequenza il ruolo di primario viene trasferito a un'altra replica (o ritorna) senza che il servizio venga arrestato.During this sequence, the role of primary is transferred to another replica (or comes back) without the service shutting down.

Infine è necessario considerare le condizioni di errore.Finally, you have to think about error or failure conditions.

Avvio di un servizio senza statoStateless service startup

Il ciclo di vita di un servizio senza stato è piuttosto semplice.The lifecycle of a stateless service is fairly straightforward. Di seguito è riportato l'ordine degli eventi:Here's the order of events:

  1. Il servizio viene costruito.The service is constructed.
  2. Questi eventi si verificano in parallelo:These events occur in parallel:
    • Viene richiamato StatelessService.createServiceInstanceListeners() e i listener restituiti vengono aperti.StatelessService.createServiceInstanceListeners() is invoked, and any returned listeners are opened. Viene chiamato CommunicationListener.openAsync() su ciascun listener.CommunicationListener.openAsync() is called on each listener.
    • Viene chiamato il metodo runAsync del servizio (StatelessService.runAsync()).The service's runAsync method (StatelessService.runAsync()) is called.
  3. Se presente, viene chiamato il metodo onOpenAsync del servizio.If present, the service's own onOpenAsync method is called. Nello specifico, viene chiamato StatelessService.onOpenAsync().Specifically, StatelessService.onOpenAsync() is called. Si tratta di un override insolito ma comunque disponibile.This is an uncommon override, but it is available.

È importante notare che non vi è alcun ordine tra la chiamata per creare e aprire i listener e la chiamata di runAsync.It's important to note that there is no ordering between the call to create and open the listeners and the call to runAsync. I listener potrebbero aprirsi prima che venga avviato runAsync.The listeners might open before runAsync is started. Analogamente, runAsync potrebbe essere chiamato prima che i listener di comunicazione siano aperti o addirittura prima che siano stati creati.Similarly, runAsync might be invoked before the communication listeners are open, or before they have even been constructed. Se è necessaria una sincronizzazione, deve essere eseguita dall'implementazione.If any synchronization is required, it must be done by the implementer. Ecco alcune delle soluzioni comuni:Here are some common solutions:

  • Talvolta i listener non possono funzionare finché non vengono create altre informazioni o eseguite altre operazioni.Sometimes listeners can't function until other information is created or other work is done. Per i servizi senza stato, queste operazioni sono in genere eseguibili nel costruttore del servizio.For stateless services, that work usually can be done in the service's constructor. Possono essere effettuate durante la chiamata di createServiceInstanceListeners() o nell'ambito della costruzione del listener stesso.It can be done during the createServiceInstanceListeners() call, or as part of the construction of the listener itself.
  • In alcuni casi il codice di runAsync non viene avviato finché i listener sono aperti.Sometimes the code in runAsync won't start until the listeners are open. In questo caso, è necessario un po' di coordinamento aggiuntivo.In this case, additional coordination is necessary. Una soluzione comune consiste nell'aggiungere un flag nei listener.A common solution is to add a flag in the listeners. Il flag indica quando i listener sono terminati.The flag indicates when the listeners have finished. Il metodo runAsync esegue questa verifica prima di continuare il lavoro effettivo.The runAsync method checks this before continuing the actual work.

Arresto di un servizio senza statoStateless service shutdown

Quando si arresta un servizio senza stato, si segue lo stesso modello, ma in senso inverso:When shutting down a stateless service, the same pattern is followed, but in reverse:

  1. Questi eventi si verificano in parallelo:These events occur in parallel:
    • Tutti i listener aperti vengono chiusi.Any open listeners are closed. Viene chiamato CommunicationListener.closeAsync() su ciascun listener.CommunicationListener.closeAsync() is called on each listener.
    • Il token di annullamento che è stato passato a runAsync() viene annullato.The cancellation token that was passed to runAsync() is canceled. La verifica della proprietà isCancelled del token di annullamento restituisce true e, se viene chiamato, il metodo throwIfCancellationRequested del token genera un'eccezione CancellationException.Checking the cancellation token's isCancelled property returns true, and if called, the token's throwIfCancellationRequested method throws a CancellationException.
  2. Al completamento di closeAsync() in ogni listener e al completamento di runAsync(), viene chiamato il metodo StatelessService.onCloseAsync() del servizio, se presente.When closeAsync() finishes on each listener and runAsync() also finishes, the service's StatelessService.onCloseAsync() method is called, if it's present. Anche in questo caso si tratta di un override insolito, ma è possibile usarlo per chiudere in modo sicuro le risorse, arrestare qualsiasi elaborazione in background, completare il salvataggio dello stato esterno o chiudere le connessioni esistenti.Again, this is not a common override, but it can be used to safely close resources, stop background processing, finish saving external state, or close down existing connections.
  3. Dopo il completamento di StatelessService.onCloseAsync(), l'oggetto servizio viene eliminato.After StatelessService.onCloseAsync() finishes, the service object is destructed.

Avvio di un servizio con statoStateful service startup

I servizi con stato hanno un modello simile ai servizi senza stato, con poche modifiche.Stateful services have a pattern that is similar to stateless services, with a few changes. L'ordine degli eventi per l'avvio di un servizio con stato è il seguente:Here's the order of events for starting a stateful service:

  1. Il servizio viene costruito.The service is constructed.
  2. Viene chiamato StatefulServiceBase.onOpenAsync().StatefulServiceBase.onOpenAsync() is called. L'override della chiamata nel servizio non è comune.This call is not commonly overridden in the service.
  3. Questi eventi si verificano in parallelo:These events occur in parallel:
    • Viene richiamato StatefulServiceBase.createServiceReplicaListeners().StatefulServiceBase.createServiceReplicaListeners() is invoked.
      • Se il servizio è di tipo primario, tutti i listener restituiti vengono aperti.If the service is a primary service, all returned listeners are opened. Viene chiamato CommunicationListener.openAsync() su ciascun listener.CommunicationListener.openAsync() is called on each listener.
      • Se il servizio è di tipo secondario, solo i listener contrassegnati come listenOnSecondary = true vengono aperti.If the service is a secondary service, only listeners marked as listenOnSecondary = true are opened. La presenza di listener aperti nei servizi secondari è meno comune.Having listeners that are open on secondaries is less common.
    • Se il servizio è attualmente di tipo primario, viene chiamato il metodo StatefulServiceBase.runAsync() del servizio.If the service is currently a primary, the service's StatefulServiceBase.runAsync() method is called.
  4. Dopo che tutte le chiamate di openAsync() del listener della replica vengono completate e dopo la chiamata di runAsync(), viene chiamato StatefulServiceBase.onChangeRoleAsync().After all the replica listener's openAsync() calls finish and runAsync() is called, StatefulServiceBase.onChangeRoleAsync() is called. L'override della chiamata nel servizio non è comune.This call is not commonly overridden in the service.

Analogamente ai servizi senza stato, nel servizio con stato non c'è alcun collegamento tra l'ordine in cui i listener vengono creati e aperti e il momento in cui viene chiamato runAsync.Similar to stateless services, in stateful service, there's no coordination between the order in which the listeners are created and opened and when runAsync is called. Se è necessario che queste operazioni siano coordinate, le soluzioni sono perlopiù simili.If you need coordination, the solutions are much the same. Ma c'è un caso aggiuntivo per il servizio con stato.But there's one additional case for stateful service. Si supponga che le chiamate in arrivo ai listener di comunicazione richiedano informazioni conservate in alcune raccolte Reliable Collections.Say that the calls that arrive at the communication listeners require information kept inside some Reliable Collections. Poiché i listener di comunicazione potrebbero venire aperti prima che le raccolte Reliable Collections possano essere lette o scritte e prima dell'avvio di runAsync, è necessario un po' di coordinamento aggiuntivo.Because the communication listeners might open before the Reliable Collections are readable or writeable, and before runAsync starts, some additional coordination is necessary. La soluzione più semplice e più comune è che i listener di comunicazione restituiscano un codice di erroreThe simplest and most common solution is for the communication listeners to return an error code. che il client usa per ripetere la richiesta.The client uses the error code to know to retry the request.

Arresto di un servizio con statoStateful service shutdown

Analogamente ai servizi senza stato, gli eventi del ciclo di vita durante l'arresto corrispondono a quelli durante l'avvio, ma invertiti.Like stateless services, the lifecycle events during shutdown are the same as during startup, but reversed. Quando viene arrestato un servizio con stato, si verificano gli eventi seguenti:When a stateful service is being shut down, the following events occur:

  1. Questi eventi si verificano in parallelo:These events occur in parallel:
    • Tutti i listener aperti vengono chiusi.Any open listeners are closed. Viene chiamato CommunicationListener.closeAsync() su ciascun listener.CommunicationListener.closeAsync() is called on each listener.
    • Il token di annullamento che è stato passato a runAsync() viene annullato.The cancellation token that was passed to runAsync() is cancelled. Una chiamata del metodo isCancelled() del token di annullamento restituisce true e, se viene chiamato, il metodo throwIfCancellationRequested() del token genera un'eccezione OperationCanceledException.A call to the cancellation token's isCancelled() method returns true, and if called, the token's throwIfCancellationRequested() method throws an OperationCanceledException.
  2. Dopo il completamento di closeAsync() in ogni listener e il completamento di runAsync(), viene chiamato il metodo StatefulServiceBase.onChangeRoleAsync() del servizio.After closeAsync() finishes on each listener and runAsync() also finishes, the service's StatefulServiceBase.onChangeRoleAsync() is called. L'override della chiamata nel servizio non è comune.This call is not commonly overridden in the service.

    Nota

    È necessario attendere il completamento di runAsync solo se la replica è una replica primaria.

  3. Dopo il completamento del metodo StatefulServiceBase.onChangeRoleAsync(), viene chiamato il metodo StatefulServiceBase.onCloseAsync().After the StatefulServiceBase.onChangeRoleAsync() method finishes, the StatefulServiceBase.onCloseAsync() method is called. Questa chiamata è un override insolito, ma comunque disponibile.This call is an uncommon override, but it is available.

  4. Dopo il completamento di StatefulServiceBase.onCloseAsync(), l'oggetto servizio viene eliminato.After StatefulServiceBase.onCloseAsync() finishes, the service object is destructed.

Scambi primari di un servizio con statoStateful service primary swaps

Quando un servizio con stato è in esecuzione, i listener di comunicazione vengono aperti e il metodo runAsync viene chiamato solo per le repliche primarie di tali servizi con stato.While a stateful service is running, communication listeners are opened and the runAsync method is called only for the primary replicas of that stateful services. Le repliche secondarie vengono costruite, ma non ricevono altre chiamate.Secondary replicas are constructed, but see no further calls. Quando un servizio con stato è in esecuzione, la replica primaria può cambiare.While a stateful service is running, the replica that's currently the primary can change. Gli eventi del ciclo di vita che una replica con stato può vedere dipendono dal fatto che la replica venga abbassata o alzata di livello durante lo scambio.The lifecycle events that a stateful replica can see depends on whether it is the replica being demoted or promoted during the swap.

Per la replica primaria abbassata di livelloFor the demoted primary

Service Fabric richiede che la replica primaria abbassata di livello interrompa l'elaborazione dei messaggi e qualsiasi attività in background.Service Fabric needs the primary replica that's demoted to stop processing messages and stop any background work. Questo passaggio è simile a quando il servizio viene arrestato.This step is similar to when the service is shut down. Una differenza è che il servizio non viene eliminato o chiuso, in quanto rimane come secondario.One difference is that the service isn't destructed or closed, because it remains as a secondary. Si verificano gli eventi seguenti:The following events occur:

  1. Questi eventi si verificano in parallelo:These events occur in parallel:
    • Tutti i listener aperti vengono chiusi.Any open listeners are closed. Viene chiamato CommunicationListener.closeAsync() su ciascun listener.CommunicationListener.closeAsync() is called on each listener.
    • Il token di annullamento che è stato passato a runAsync() viene annullato.The cancellation token that was passed to runAsync() is canceled. Una verifica del metodo isCancelled() del token di annullamento restituisce true.A check of the cancellation token's isCancelled() method returns true. Se chiamato, il metodo throwIfCancellationRequested() del token genera un'eccezione OperationCanceledException.If called, the token's throwIfCancellationRequested() method throws an OperationCanceledException.
  2. Dopo il completamento di closeAsync() in ogni listener e il completamento di runAsync(), viene chiamato il metodo StatefulServiceBase.onChangeRoleAsync() del servizio.After closeAsync() finishes on each listener and runAsync() also finishes, the service's StatefulServiceBase.onChangeRoleAsync() is called. L'override della chiamata nel servizio non è comune.This call is not commonly overridden in the service.

Per la replica secondaria alzata di livelloFor the promoted secondary

In modo analogo, Service Fabric richiede che la replica secondaria alzata di livello inizi ad ascoltare i messaggi in transito e avvii le attività in background necessarie.Similarly, Service Fabric needs the secondary replica that's promoted to start listening for messages on the wire, and to start any background tasks that it needs to complete. Questo processo è simile a quando il servizio viene creato.This process is similar to when the service is created. La differenza è che la replica stessa esiste già.The difference is that the replica itself already exists. Si verificano gli eventi seguenti:The following events occur:

  1. Questi eventi si verificano in parallelo:These events occur in parallel:
    • Viene richiamato StatefulServiceBase.createServiceReplicaListeners() e i listener restituiti vengono aperti.StatefulServiceBase.createServiceReplicaListeners() is invoked and any returned listeners are opened. Viene chiamato CommunicationListener.openAsync() su ciascun listener.CommunicationListener.openAsync() is called on each listener.
    • Viene chiamato il metodo StatefulServiceBase.runAsync() del servizio.The service's StatefulServiceBase.runAsync() method is called.
  2. Dopo che tutte le chiamate di openAsync() del listener della replica vengono completate e dopo la chiamata di runAsync(), viene chiamato StatefulServiceBase.onChangeRoleAsync().After all the replica listener's openAsync() calls finish and runAsync() is called, StatefulServiceBase.onChangeRoleAsync() is called. L'override della chiamata nel servizio non è comune.This call is not commonly overridden in the service.

Problemi comuni durante l'arresto del servizio con stato e l'abbassamento di livello primarioCommon issues during stateful service shutdown and primary demotion

Service Fabric modifica lo stato primario di un servizio con stato per diversi motivi.Service Fabric changes the primary of a stateful service for multiple reasons. Le ragioni più comuni sono il ribilanciamento del cluster e l'aggiornamento dell'applicazione.The most common reasons are cluster rebalancing and application upgrade. Durante queste operazioni, è importante che il servizio rispetti il cancellationToken.During these operations, it's important that the service respects the cancellationToken. Questo vale anche durante l'arresto normale del servizio, ad esempio se il servizio è stato eliminato.This also applies during normal service shutdown, such as if the service was deleted.

I servizi che non gestiscono correttamente l'annullamento possono essere soggetti a diversi problemi.Services that don't handle cancellation cleanly can experience several issues. Queste operazioni sono lente perché Service Fabric attende l'arresto normale dei servizi.These operations are slow because Service Fabric waits for the services to stop gracefully. Questo può infine comportare la mancata riuscita degli aggiornamenti che raggiungono il timeout ed eseguono il rollback.This can ultimately lead to failed upgrades that time out and rollback. Il mancato rispetto del token di annullamento può anche provocare uno sbilanciamento dei cluster.Failure to honor the cancellation token also can cause imbalanced clusters. I cluster diventano sbilanciati perché viene eseguito un accesso frequente ai nodi.Clusters become unbalanced because nodes get hot. Tuttavia i servizi non possono essere ribilanciati in quanto il loro spostamento richiede troppo tempo.However, the services can't be rebalanced because it takes too long to move them elsewhere.

Trattandosi di servizi con stato, è anche probabile che i servizi usino raccolte Reliable Collections.Because the services are stateful, it's also likely that the services use Reliable Collections. In Service Fabric, quando un servizio primario viene abbassato di livello, una delle prime cose che accade è che viene revocato l'accesso in scrittura allo stato sottostante.In Service Fabric, when a primary is demoted, one of the first things that happens is that write access to the underlying state is revoked. Ciò comporta una seconda serie di problemi che potrebbero influire sul ciclo di vita del servizio.This leads to a second set of issues that might affect the service lifecycle. Le raccolte restituiscono eccezioni in base alla tempistica e al fatto che la replica venga spostata o arrestata.The collections return exceptions based on the timing and whether the replica is being moved or shut down. È importante gestire queste eccezioni correttamente.It's important to handle these exceptions correctly.

Le eccezioni generate da Service Fabric sono permanenti (FabricException) o temporanee (FabricTransientException).Exceptions thrown by Service Fabric are either permanent (FabricException) or transient (FabricTransientException). Le eccezioni permanenti dovrebbero essere registrate e generate,Permanent exceptions should be logged and thrown. mentre quelle temporanee possono essere ripetute in base a una logica di ripetizione.Transient exceptions can be retried based on retry logic.

Una parte importante del test e della convalida di Reliable Services consiste nella gestione delle eccezioni che derivano dall'uso di ReliableCollections in combinazione con gli eventi del ciclo di vita del servizio.An important part of testing and validating Reliable Services is handling the exceptions that come from using the ReliableCollections in conjunction with service lifecycle events. Si consiglia sempre di eseguire il servizio in condizioni di carico.We recommend that you always run your service under load. È inoltre opportuno eseguire aggiornamenti e test CHAOS prima della distribuzione nell'ambiente di produzione.You should also perform upgrades and chaos testing before deploying to production. Questi passaggi di base contribuiscono ad assicurare che il servizio sia implementato correttamente e che gestisca gli eventi del ciclo di vita nel modo giusto.These basic steps help ensure that your service is implemented correctly, and that it handles lifecycle events correctly.

Note sul ciclo di vita del servizioNotes on service lifecycle

  • Entrambe le chiamate del metodo runAsync() e di createServiceInstanceListeners/createServiceReplicaListeners sono facoltative.Both the runAsync() method and the createServiceInstanceListeners/createServiceReplicaListeners calls are optional. Un servizio potrebbe averne una, entrambe o nessuna.A service might have one, both, or neither. Ad esempio, se il servizio esegue tutte le attività in risposta alle chiamate dell'utente, non è necessario implementare runAsync().For example, if the service does all its work in response to user calls, there's no need for it to implement runAsync(). Sono necessari solo i listener di comunicazione e il codice associato.Only the communication listeners and their associated code are necessary. Analogamente, la creazione e la restituzione di listener di comunicazione sono facoltative.Similarly, creating and returning communication listeners is optional. Il servizio potrebbe avere solo attività in background da eseguire, pertanto è necessario implementare solo runAsync().The service might have only background work to do, so it only needs to implement runAsync().
  • È un comportamento valido per un servizio completare runAsync() correttamente e ritornare.It's valid for a service to complete runAsync() successfully and return from it. Questa non è considerata una condizione di erroreThis isn't considered a failure condition. e rappresenta il completamento dell'attività in background del servizio.It represents the background work of the service finishing. Per i servizi Reliable Services con stato viene chiamato nuovamente runAsync() se il servizio è stato abbassato dal livello primario e poi alzato di nuovo al livello primario.For stateful Reliable Services, runAsync() would be called again if the service is demoted from primary, and then promoted back to primary.
  • Se un servizio esce da runAsync() generando un'eccezione imprevista, questo è un errore.If a service exits from runAsync() by throwing some unexpected exception, this is a failure. L'oggetto servizio viene arrestato e viene segnalato un errore di integrità.The service object is shut down, and a health error is reported.
  • Anche se non c'è alcun limite di tempo per il completamento di questi metodi, si perde immediatamente la possibilità di scrivere.Although there's no time limit on returning from these methods, you immediately lose the ability to write. Pertanto, non è possibile completare alcuna operazione effettiva.Therefore, you can't complete any real work. Si consiglia di completare al più presto la richiesta di annullamento ricevuta.We recommend that you return as quickly as possible upon receiving the cancellation request. Se il servizio non risponde a queste chiamate API entro un intervallo di tempo ragionevole, Service Fabric potrebbe terminare forzatamente il servizio.If your service doesn't respond to these API calls in a reasonable amount of time, Service Fabric might forcibly terminate your service. In genere ciò accade solo durante gli aggiornamenti delle applicazioni o quando viene eliminato un servizio.Usually, this happens only during application upgrades or when a service is being deleted. Questo timeout è di 15 minuti per impostazione predefinita.This timeout is 15 minutes by default.
  • Gli errori nel percorso onCloseAsync() comportano la chiamata di onAbort().Failures in the onCloseAsync() path result in onAbort() being called. Questa chiamata rappresenta l'ultima e migliore opportunità del servizio di pulire e rilasciare le risorse che sono state richieste.This call is a last-chance, best-effort opportunity for the service to clean up and release any resources that they have claimed. Questo metodo in genere viene chiamato quando viene rilevato un errore permanente sul nodo o quando Service Fabric non è in grado di gestire in modo affidabile il ciclo di vita dell'istanza del servizio a causa di errori interni.This is generally called when a permanent fault is detected on the node, or when Service Fabric cannot reliably manage the service instance's lifecycle due to internal failures.
  • OnChangeRoleAsync() viene chiamato quando la replica del servizio con stato cambia ruolo, ad esempio primario o secondario.OnChangeRoleAsync() is called when the stateful service replica is changing role, for example to primary or secondary. Alle repliche primarie viene assegnato lo stato di scrittura (sono autorizzate a creare raccolte Reliable Collections e a scrivervi).Primary replicas are given write status (are allowed to create and write to Reliable Collections). Alle repliche secondarie viene assegnato lo stato di lettura (possono solo leggere da raccolte Reliable Collections esistenti).Secondary replicas are given read status (can only read from existing Reliable Collections). La maggior parte delle operazioni in un servizio con stato viene eseguita nella replica primaria.Most work in a stateful service is performed at the primary replica. Le repliche secondarie possono eseguire la convalida di sola lettura, la generazione di report, il data mining o altri processi di sola lettura.Secondary replicas can perform read-only validation, report generation, data mining, or other read-only jobs.

Passaggi successiviNext steps