Panoramica del ciclo di vita di Reliable ServicesReliable Services lifecycle overview

Quando si pensa al ciclo di vita di Reliable Services di Azure Service Fabric, le nozioni di base del ciclo di vita sono quelle più importanti.When you're thinking about the lifecycles of Azure Service Fabric Reliable Services, the basics of the lifecycle are the most important. In generale, il ciclo di vita include quanto segue:In general, the lifecycle includes the following:

  • 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.The services have an opportunity to construct and return zero or more listeners.
    • Qualsiasi listener restituito viene aperto, per consentire la comunicazione con il servizio.Any returned listeners are opened, allowing communication with the service.
    • Viene chiamato il metodo RunAsync del servizio, che consente al servizio di eseguire operazioni a esecuzione prolungata o in background.The service's RunAsync method is called, allowing the service to do long-running tasks or background work.
  • Durante l'arresto:During shutdown:
    • Il token di annullamento passato a RunAsync viene annullato e i listener vengono chiusi.The cancellation token passed to RunAsync is canceled, and the listeners are closed.
    • Una volta chiusi i listener, viene eliminato l'oggetto servizio stesso.After the listeners close, the service object itself is destructed.

Sono disponibili informazioni dettagliate sull'esatto ordine di questi eventi.There are details around the exact ordering of these events. L'ordine degli eventi può cambiare leggermente a seconda che il servizio Reliable Services sia con o senza stato.The order of events can change slightly depending on whether the Reliable Service is stateless or stateful. Per i servizi con stato, è inoltre necessario gestire lo scenario di scambio del ruolo primario.In addition, for stateful services, we must deal with the Primary swap scenario. Durante tale sequenza il ruolo di primario viene trasferito a un'altra replica (o ritorna) senza l'arresto del servizio.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, we must think about error or failure conditions.

Avvio di un servizio senza statoStateless service startup

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

  1. Il servizio viene costruito.The service is constructed.
  2. Si verificano quindi due eventi in parallelo:Then, in parallel, two things happen:
    • Viene richiamato StatelessService.CreateServiceInstanceListeners() e i listener restituiti vengono aperti.StatelessService.CreateServiceInstanceListeners() is invoked and any returned listeners are opened. Viene richiamato ICommunicationListener.OpenAsync() su ogni listener.ICommunicationListener.OpenAsync() is called on each listener.
    • Viene chiamato il metodo StatelessService.RunAsync() del servizio.The service's StatelessService.RunAsync() method is called.
  3. Se presente, viene chiamato il metodo StatelessService.OnOpenAsync() del servizio.If present, the service's StatelessService.OnOpenAsync() method is called. Questa chiamata è un override insolito, ma comunque disponibile.This call is an uncommon override, but it is available. In questo momento è possibile avviare attività estese di inizializzazione del servizio.Extended service initialization tasks can be started at this time.

Tenere presente che non c'è alcun ordine tra le chiamate per creare e aprire i listener e RunAsync.Keep in mind that there is no ordering between the calls to create and open the listeners and RunAsync. I listener possono essere aperti prima dell'avvio di RunAsync.The listeners can open before RunAsync is started. Analogamente, è possibile richiamare RunAsync prima dell'apertura o anche della costruzione dei listener di comunicazione.Similarly, you can invoke RunAsync before the communication listeners are open or even constructed. Se è necessaria una sincronizzazione, la si lascia come esercizio per il responsabile dell'implementazione.If any synchronization is required, it is left as an exercise to the implementer. Ecco alcune delle soluzioni comuni:Here are some common solutions:

  • Talvolta i listener non possono funzionare fino a quando non vengono create altre informazioni o eseguite determinate operazioni.Sometimes listeners can't function until some other information is created or work is done. Per i servizi senza stato, tali operazioni possono essere in genere eseguite in altre posizioni, ad esempio:For stateless services, that work can usually be done in other locations, such as the following:
    • Nel costruttore del servizio.In the service's constructor.
    • Durante la chiamata di CreateServiceInstanceListeners().During the CreateServiceInstanceListeners() call.
    • Nell'ambito della costruzione del listener stesso.As a part of the construction of the listener itself.
  • In alcuni casi il codice di RunAsync non viene avviato fino a quando i listener non vengono aperti.Sometimes the code in RunAsync doesn'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 è rappresentata dalla presenza di un flag nei listener che indica quando vengono completati.One common solution is that there is a flag within the listeners that indicates when they have finished. Questo flag viene quindi controllato in RunAsync prima di continuare con le operazioni effettive.This flag is then checked in RunAsync before continuing to actual work.

Arresto di un servizio senza statoStateless service shutdown

Per l'arresto di un servizio senza stato, viene seguito lo stesso modello, ma in ordine inverso:For shutting down a stateless service, the same pattern is followed, just in reverse:

  1. In parallelo:In parallel:
    • Tutti i listener aperti vengono chiusi.Any open listeners are closed. Viene richiamato ICommunicationListener.CloseAsync() su ogni listener.ICommunicationListener.CloseAsync() is called on each listener.
    • Il token di annullamento passato a RunAsync() viene annullato.The cancellation token passed to RunAsync() is canceled. La verifica della proprietà IsCancellationRequested del token di annullamento restituisce true e, se chiamato, il metodo ThrowIfCancellationRequested del token genera un'eccezione OperationCanceledException.A check of the cancellation token's IsCancellationRequested property 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 StatelessService.OnCloseAsync() del servizio, se presente.After CloseAsync() finishes on each listener and RunAsync() also finishes, the service's StatelessService.OnCloseAsync() method is called, if present. OnCloseAsync viene chiamato quando l'istanza del servizio senza stato sta per essere arrestata normalmente.OnCloseAsync is called when the stateless service instance is going to be gracefully shut down. Ciò può verificarsi quando il codice del servizio viene aggiornato, l'istanza del servizio viene spostata a causa del bilanciamento del carico o viene rilevato un errore temporaneo.This can occur when the service's code is being upgraded, the service instance is being moved due to load balancing, or a transient fault is detected. Solitamente non viene eseguito l'override di StatelessService.OnCloseAsync(), 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.It is uncommon to override StatelessService.OnCloseAsync(), 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 similar pattern to stateless services, with a few changes. Quando si avvia un servizio con stato, l'ordine degli eventi è il seguente:For starting up a stateful service, the order of events is as follows:

  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. Si verificano gli eventi seguenti, in parallelo:The following things happen 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 richiamato ICommunicationListener.OpenAsync() su ogni listener.ICommunicationListener.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 those 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, 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, 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. C'è un caso aggiuntivo per il servizio con stato.There is 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 could open before the reliable collections are readable or writeable, and before RunAsync could start, some additional coordination is necessary. La soluzione più semplice e più comune è che i listener di comunicazione restituiscano un codice di errore che il client usa per ripetere la richiesta.The simplest and most common solution is for the communication listeners to return an error code that the client uses 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. In parallelo:In parallel:
    • Tutti i listener aperti vengono chiusi.Any open listeners are closed. Viene richiamato ICommunicationListener.CloseAsync() su ogni listener.ICommunicationListener.CloseAsync() is called on each listener.
    • Il token di annullamento passato a RunAsync() viene annullato.The cancellation token passed to RunAsync() is canceled. La verifica della proprietà IsCancellationRequested del token di annullamento restituisce true e, se chiamato, il metodo ThrowIfCancellationRequested del token genera un'eccezione OperationCanceledException.A check of the cancellation token's IsCancellationRequested property 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 è di tipo primario.

  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 della replica primaria di un servizio con statoStateful service Primary swaps

Quando un servizio con stato è in esecuzione, solo per le repliche primarie di tali servizi con stato i listener di comunicazione vengono aperti e il metodo RunAsync viene chiamato.While a stateful service is running, only the Primary replicas of that stateful services have their communication listeners opened and their RunAsync method called. 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. Che cosa significa questo in termini di eventi del ciclo di vita che una replica può vedere?What does this mean in terms of the lifecycle events that a replica can see? Il comportamento che la replica con stato vede dipende dal fatto che la replica venga abbassata o alzata di livello durante lo scambio.The behavior the stateful replica sees depends on whether it is the replica being demoted or promoted during the swap.

Per la replica primaria abbassata di livelloFor the Primary that's demoted

Per la replica primaria abbassata di livello, Service Fabric richiede che questa replica interrompa l'elaborazione dei messaggi e qualsiasi attività in background che sta eseguendo.For the Primary replica that's demoted, Service Fabric needs this replica to stop processing messages and quit any background work it is doing. Di conseguenza, questo passaggio è simile a quando il servizio viene arrestato.As a result, this step looks like it did 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. Vengono chiamate le API seguenti:The following APIs are called:

  1. In parallelo:In parallel:
    • Tutti i listener aperti vengono chiusi.Any open listeners are closed. Viene richiamato ICommunicationListener.CloseAsync() su ogni listener.ICommunicationListener.CloseAsync() is called on each listener.
    • Il token di annullamento passato a RunAsync() viene annullato.The cancellation token passed to RunAsync() is canceled. La verifica della proprietà IsCancellationRequested del token di annullamento restituisce true e, se chiamato, il metodo ThrowIfCancellationRequested del token genera un'eccezione OperationCanceledException.A check of the cancellation token's IsCancellationRequested property 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.

Per la replica secondaria alzata di livelloFor the Secondary that's promoted

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 start any background tasks it needs to complete. Di conseguenza, questo processo è simile a quando viene creato il servizio, ad eccezione del fatto che la replica esiste già.As a result, this process looks like it did when the service is created, except that the replica itself already exists. Vengono chiamate le API seguenti:The following APIs are called:

  1. In parallelo:In parallel:
    • Viene richiamato StatefulServiceBase.CreateServiceReplicaListeners() e i listener restituiti vengono aperti.StatefulServiceBase.CreateServiceReplicaListeners() is invoked and any returned listeners are opened. Viene richiamato ICommunicationListener.OpenAsync() su ogni listener.ICommunicationListener.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 di un servizio con stato e l'abbassamento di livello di una replica primariaCommon issues during stateful service shutdown and Primary demotion

Service Fabric modifica lo stato Primario di un servizio con stato per una serie di motivi.Service Fabric changes the Primary of a stateful service for a variety of reasons. I più comuni sono il ribilanciamento del cluster e l'aggiornamento dell'applicazione.The most common are cluster rebalancing and application upgrade. Durante queste operazioni (nonché durante il normale arresto del servizio, come è possibile notare in caso di eliminazione del servizio), è importante che il servizio rispetti CancellationToken.During these operations (as well as during normal service shutdown, like you'd see if the service was deleted), it is important that the service respect the CancellationToken.

I servizi che non gestiscono correttamente l'annullamento possono essere soggetti a diversi problemi.Services that do not 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 timeout ed eseguono il rollback.This can ultimately lead to failed upgrades that time out and roll back. Il mancato rispetto del token di annullamento può anche provocare uno sbilanciamento dei cluster.Failure to honor the cancellation token can also cause imbalanced clusters. I cluster diventano sbilanciati perché viene eseguito un accesso frequente ai nodi, ma i servizi non possono essere ribilanciati in quanto il loro spostamento richiede troppo tempo.Clusters become unbalanced because nodes get hot, but the services can't be rebalanced because it takes too long to move them elsewhere.

Poiché si tratta di servizi con stato, è anche probabile che usino raccolte Reliable Collections.Because the services are stateful, it is also likely that they use the 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 un secondo set di problemi che possono influire sul ciclo di vita del servizio.This leads to a second set of issues that can 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. Queste eccezioni devono essere gestite correttamente.These exceptions should be handled correctly. Le eccezioni generate da Service Fabric rientrano nelle categorie permanente (FabricException) e temporanea (FabricTransientException).Exceptions thrown by Service Fabric fall into permanent (FabricException) and transient (FabricTransientException) categories. Le eccezioni permanenti devono essere registrate e generate, mentre quelle temporanee possono essere ripetute in base a una logica di ripetizione.Permanent exceptions should be logged and thrown while the transient exceptions can be retried based on some retry logic.

La gestione delle eccezioni che derivano dall'uso di ReliableCollections in combinazione con gli eventi del ciclo di vita del servizio è una parte importante di test e convalida di un servizio Reliable.Handling the exceptions that come from use of the ReliableCollections in conjunction with service lifecycle events is an important part of testing and validating a Reliable Service. Si consiglia sempre di eseguire il servizio in condizioni di carico durante l'esecuzione di aggiornamenti e test CHAOS prima della distribuzione nell'ambiente di produzione.We recommend that you always run your service under load while performing upgrades and chaos testing before deploying to production. Questi passaggi di base contribuiscono ad assicurare che il servizio sia implementato correttamente e gestisca gli eventi del ciclo di vita nel modo giusto.These basic steps help ensure that your service is correctly implemented and handles lifecycle events correctly.

Note sul ciclo di vita del servizioNotes on the service lifecycle

  • Entrambe le chiamate del metodo RunAsync() e di CreateServiceReplicaListeners/CreateServiceInstanceListeners sono facoltative.Both the RunAsync() method and the CreateServiceReplicaListeners/CreateServiceInstanceListeners calls are optional. Un servizio può averne una, entrambe o nessuna.A service can have one of them, 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 is 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 dei listener di comunicazione sono operazioni facoltative, in quanto il servizio può avere solo operazioni in background da eseguire e perciò richiedere solo l'implementazione di RunAsync().Similarly, creating and returning communication listeners is optional, as the service can have only background work to do, and so only needs to implement RunAsync().
  • È un comportamento valido per un servizio completare RunAsync() correttamente e ritornare.It is valid for a service to complete RunAsync() successfully and return from it. Il completamento non è una condizione di errore.Completing is not a failure condition. Il completamento di RunAsync() indica che le operazioni in background del servizio sono terminate.Completing RunAsync() indicates that the background work of the service has finished. Per i servizi Reliable Services con stato, viene chiamato di nuovo RunAsync() se la replica è stata abbassata di livello da primaria a secondaria e quindi alzata di nuovo al livello primario.For stateful reliable services, RunAsync() is called again if the replica is demoted from Primary to Secondary 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 constitutes 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 nelle raccolte Reliable Collections e quindi non è possibile completare alcuna operazione effettiva.Although there is no time limit on returning from these methods, you immediately lose the ability to write to Reliable Collections, and therefore, cannot complete any real work. Si consiglia di completare al più presto la richiesta di annullamento ricevuta.We recommended 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 può terminarlo.If your service does not respond to these API calls in a reasonable amount of time, Service Fabric can forcibly terminate your service. In genere ciò accade solo durante gli aggiornamenti delle applicazioni o quando viene eliminato un servizio.Usually this only happens 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(), che rappresenta l'ultima e migliore opportunità del servizio di pulire e rilasciare le risorse che sono state richieste.Failures in the OnCloseAsync() path result in OnAbort() being called, which 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