Información general del ciclo de vida de Reliable Services
Al analizar los ciclos de vida de Reliable Services de Azure Service Fabric, los conceptos básicos del ciclo de vida son lo más importante. En general, el ciclo de vida incluye lo siguiente:
- Durante el inicio:
- Se construyen los servicios.
- Los servicios tienen la oportunidad de construir y devolver cero o más agentes de escucha.
- Se abre cualquier agente de escucha devuelto, lo cual permite la comunicación con el servicio.
- Se llama al método RunAsync del servicio, lo cual permite a este último realizar tareas de ejecución prolongada o trabajo en segundo plano.
- Durante el cierre:
- Se cancela el token de cancelación pasado a RunAsync y se cierran los agentes de escucha.
- Una vez cerrados los agentes de escucha, se destruye el propio objeto de servicio.
Hay información sobre la ordenación exacta de estos eventos. El orden de eventos puede cambiar ligeramente dependiendo de si Reliable Services tiene o no tiene estado. Además, para los servicios con estado, tenemos que tratar con el escenario de intercambio principal. Durante esta secuencia, el rol Principal se transfiere a otra réplica (o se devuelve) sin que el servicio tenga que cerrarse. Por último, hay que pensar en condiciones de error.
Inicio de un servicio sin estado
El ciclo de vida de un servicio sin estado es sencillo. Este es el orden de los eventos:
- Se construye el servicio.
- Se invoca
StatelessService.CreateServiceInstanceListeners()
y se abren los agentes de escucha devueltos. Se llama aICommunicationListener.OpenAsync()
en cada uno de los agentes de escucha. - A continuación, suceden dos cosas simultáneamente:
- Se llama al método
StatelessService.RunAsync()
del servicio. - Si está presente, se llama al método
StatelessService.OnOpenAsync()
del servicio. Esta llamada es una invalidación poco habitual, pero está disponible. En este momento, se pueden iniciar las tareas de inicialización del servicio ampliado.
- Se llama al método
Cierre de un servicio sin estado
Al cerrar un servicio sin estado, se sigue el mismo patrón, solo que en orden inverso:
- Todos los agentes de escucha abiertos se cierran. Se llama a
ICommunicationListener.CloseAsync()
en cada uno de los agentes de escucha. - Se cancela el token de cancelación que se pasó a
RunAsync()
. La comprobación de la propiedadIsCancellationRequested
del token de cancelación devuelve el valor True y, si se llama al métodoThrowIfCancellationRequested
del token, se inicia una excepciónOperationCanceledException
. Service Fabric espera a queRunAsync()
se complete. - Una vez que finaliza
RunAsync()
, se llama al métodoStatelessService.OnCloseAsync()
del servicio, si existe. Se llama a OnCloseAsync cuando la instancia de servicio sin estado se va a apagar correctamente. Esto puede ocurrir cuando se está actualizando el código de servicio, cuando se está moviendo la instancia de servicio debido al equilibrio de carga o se detecta un error transitorio. No es frecuente invalidarStatelessService.OnCloseAsync()
, pero puede utilizarse para cerrar de manera segura los recursos, detener el procesamiento en segundo plano, terminar de guardar el estado externo o cerrar las conexiones existentes. - Una vez finalizado
StatelessService.OnCloseAsync()
, se destruye el objeto de servicio.
Inicio de un servicio con estado
Los servicios con estado tienen un patrón similar al de los servicios sin estado, con unos pocos cambios. Al iniciarse un servicio con estado, el orden de los eventos es el siguiente:
Se construye el servicio.
Se llama a
StatefulServiceBase.OnOpenAsync()
. Por lo general, la llamada no se invalida en el servicio.Se invoca a
StatefulServiceBase.CreateServiceReplicaListeners()
.- Si se trata de un servicio principal, se abren todos los agentes de escucha devueltos. Se llama a
ICommunicationListener.OpenAsync()
en cada uno de los agentes de escucha. - Si se trata de un servicio secundario, solamente se abren los agentes de escucha con la marca
ListenOnSecondary = true
. No es muy frecuente tener agentes de escucha abiertos en servicios secundarios.
- Si se trata de un servicio principal, se abren todos los agentes de escucha devueltos. Se llama a
En paralelo:
- Si en la actualidad el servicio es un servicio principal, se llama al método
StatefulServiceBase.RunAsync()
del servicio. - Se llama a
StatefulServiceBase.OnChangeRoleAsync()
. Por lo general, la llamada no se invalida en el servicio.
Nota:
Para una nueva réplica secundaria, se llama a
StatefulServiceBase.OnChangeRoleAsync()
dos veces. Una vez después del paso 2, cuando se convierte en una réplica secundaria inactiva y de nuevo durante el paso 4, cuando se convierte en una secundaria activa. Para más información sobre el ciclo de vida de réplicas e instancias, lea Ciclo de vida de las réplicas y las instancias.- Si en la actualidad el servicio es un servicio principal, se llama al método
Cierre de un servicio con estado
De forma similar a los servicios sin estado, los eventos de ciclo de vida durante el cierre son los mismos que durante el inicio, pero a la inversa. Cuando un servicio con estado se está cerrando, se producen los siguientes eventos:
Todos los agentes de escucha abiertos se cierran. Se llama a
ICommunicationListener.CloseAsync()
en cada uno de los agentes de escucha.Se llama al método
StatefulServiceBase.OnCloseAsync()
. Esta llamada es una invalidación poco habitual, pero está disponible.Se cancela el token de cancelación que se pasó a
RunAsync()
. La comprobación de la propiedadIsCancellationRequested
del token de cancelación devuelve el valor True y, si se llama al métodoThrowIfCancellationRequested
del token, se inicia una excepciónOperationCanceledException
. Service Fabric espera a queRunAsync()
se complete.Nota:
Solo es necesario esperar a que finalice RunAsync si esta réplica es una réplica principal.
Una vez finalizado
StatefulServiceBase.RunAsync()
, se destruye el objeto de servicio.
Intercambios de servicios con estado principales
Durante la ejecución de un servicio con estado, solo se abren los agentes de escucha de comunicación y se llama al método RunAsync de los servicios con estado principales. Se construyen réplicas secundarias, pero no reciben más llamadas. Durante la ejecución de un servicio con estado, la réplica que es actualmente la principal puede cambiar como resultado de la optimización de equilibrio de clúster o un error. ¿Cómo afecta esto a los eventos de ciclo de vida que puede ver una réplica? El comportamiento de la réplica con estado depende de si es la réplica que está subiendo o bajando de categoría.
En el caso de que la principal baje de categoría
Si la réplica principal baja de categoría, Service Fabric necesita que esta réplica deje de procesar mensajes y que cierre cualquier trabajo que esté realizando en segundo plano. Como resultado, este paso es similar al del servicio cuando se cierra. Se diferencia en que el servicio no se destruye ni se cierra, puesto que permanece como un elemento secundario. Se llama a las API siguientes:
- Todos los agentes de escucha abiertos se cierran. Se llama a
ICommunicationListener.CloseAsync()
en cada uno de los agentes de escucha. - Se cancela el token de cancelación que se pasó a
RunAsync()
. La comprobación de la propiedadIsCancellationRequested
del token de cancelación devuelve el valor True y, si se llama al métodoThrowIfCancellationRequested
del token, se inicia una excepciónOperationCanceledException
. Service Fabric espera a queRunAsync()
se complete. - Se abren los clientes de escucha marcados como listenOnSecondary = true.
- Se llama al servicio
StatefulServiceBase.OnChangeRoleAsync()
. Por lo general, la llamada no se invalida en el servicio.
En el caso de que la secundaria suba de categoría
De igual modo, Service Fabric necesita que la réplica secundaria que sube de categoría comience a escuchar los mensajes de la conexión e inicie las tareas en segundo plano que debe completar. Como resultado, este proceso es similar a cuando se crea el servicio, salvo que la propia réplica ya existe. Se llama a las API siguientes:
- Se llama a
ICommunicationListener.CloseAsync()
para todos los clientes de escucha abiertos (marcados con listenOnSecondary = true). - Se abren todos los clientes de escucha de la comunicación. Se llama a
ICommunicationListener.OpenAsync()
en cada uno de los agentes de escucha. - En paralelo:
- Se llama al método
StatefulServiceBase.RunAsync()
del servicio. - Se llama a
StatefulServiceBase.OnChangeRoleAsync()
. Por lo general, la llamada no se invalida en el servicio.
- Se llama al método
Nota:
Se llama a CreateServiceReplicaListeners
solo una vez y no se llama de nuevo durante el proceso de promoción o degradación de réplicas; se usan las mismas instancias de ServiceReplicaListener
, pero se crean nuevas instancias de ICommunicationListener
(llamando al método ServiceReplicaListener.CreateCommunicationListener
) después de cerrar las instancias anteriores.
Problemas habituales durante la degradación de la categoría principal y el cierre de un servicio con estado
Service Fabric cambia la categoría principal del un servicio con estado por diferentes razones. La más frecuente es el reequilibrio de clusteres y la actualización de aplicaciones. Durante estas operaciones (así como durante el cierre normal del servicio, al igual que ocurriría si el servicio se eliminara), es importante que el servicio respete el objeto CancellationToken
.
Los servicios que no administren correctamente la cancelación pueden experimentar errores. El rendimiento de estas operaciones es lento, ya que Service Fabric espera que los servicios se detengan sin que se produzcan errores. En última instancia, esto puede producir errores en las actualizaciones, que pueden agotar el tiempo de espera o revertirse. Si no se respeta el token de cancelación, también puede producirse un desequilibrio en los clústeres. Este desequilibrio puede producirse porque los nodos pueden sobrecargarse sin que los servicios puedan reequilibrarse, dado que se tarda algún tiempo en transferirlos a otro sitio.
Como los servicios tienen estado, también es probable que utilicen Reliable Collections. En Service Fabric, cuando un servicio principal se degrada de nivel, una de las primeras cosas que ocurren es que se revoca el acceso de escritura al estado subyacente. Esto genera una serie problemas secundarios que pueden afectar al ciclo de vida del servicio. Las colecciones devuelven excepciones en función del momento elegido y de si la réplica se está transfiriendo a otro lugar o cerrando. Estas excepciones deberían administrarse correctamente. Las excepciones iniciadas por Service Fabric pueden corresponder a dos categorías: permanentes (FabricException
) y transitorias (FabricTransientException
). Las excepciones permanentes tienen que registrarse e iniciarse, mientras que las transitorias pueden volver a intentarse con arreglo a una determinada lógica de recuperación.
Administrar las excepciones que proceden del uso de ReliableCollections
junto con los acontecimientos del ciclo de vida del servicio es una parte importante del proceso de comprobación y validación de un servicio de Reliable Services. Se recomienda ejecutar siempre el servicio con carga mientras se realizan actualizaciones y pruebas de caos antes de realizar una implementación en producción. Estos pasos básicos ayudan a garantizar que el servicio está implementado correctamente y puede administrar los eventos del ciclo de vida correctamente.
Notas sobre el ciclo de vida del servicio
- Tanto el método
RunAsync()
como las llamadas aCreateServiceReplicaListeners/CreateServiceInstanceListeners
son opcionales. Un servicio puede tener uno, ambos o ninguno. Por ejemplo, si el servicio realiza todo su trabajo en respuesta a las llamadas del usuario, no es necesario que implementeRunAsync()
. Solo son necesarios los agentes de escucha de comunicación y el código asociado. Del mismo modo, la creación y devolución de los agentes de escucha de comunicación es opcional, ya que el servicio tal vez solo tiene que realizar trabajo en segundo plano, por lo que solo necesita implementarRunAsync()
. - Un servicio puede completar
RunAsync()
correctamente y volver desde este. La finalización no es una condición de error. La finalización deRunAsync()
indica que el trabajo en segundo plano del servicio ha finalizado. En el caso de los servicios con estado de Reliable Services, se llamaría de nuevo aRunAsync()
si la réplica se degradara de la categoría principal a la secundaria y se promoviera de nuevo a la categoría principal. - Si un servicio sale de
RunAsync()
iniciando una excepción inesperada, se considera un error. El objeto de servicio se cierra y se notifica el error de estado. - Aunque no hay un límite de tiempo para que se devuelvan resultados de estos métodos, se pierde inmediatamente la posibilidad de escribir en Reliable Collections y, por lo tanto, no se puede realizar ningún trabajo real. Se recomienda que devuelva resultados lo antes posible tras recibir la solicitud de cancelación. Si su servicio no responde a estas llamadas a la API en un intervalo de tiempo razonable, Service Fabric puede forzar la finalización del servicio. Esto solo suele pasar durante las actualizaciones de aplicación o cuando se elimina un servicio. Este tiempo de espera es de 15 minutos de manera predeterminada.
- Los errores en la ruta
OnCloseAsync()
dan como resultado una llamada aOnAbort()
, que es una oportunidad como último recurso para hacer todo lo posible para que el servicio limpie y libere cualquier recurso que haya reclamado. Normalmente se llama cuando se detecta un error permanente en el nodo o cuando Service Fabric no puede administrar el ciclo de vida de la instancia de servicio debido a errores internos. - Se llama a
OnChangeRoleAsync()
cuando la réplica del servicio con estado cambia de rol, por ejemplo, a principal o secundario. Las réplicas principales reciben el estado de escritura (se les permite crear y escribir en Reliable Collections). Las réplicas secundarias reciben el estado de lectura (solo pueden leer desde Reliable Collections existentes). La mayoría del trabajo en un servicio con estado se lleva a cabo en la réplica principal. Las réplicas secundarias pueden realizar validación de solo lectura, generación de informes, minería de datos u otros trabajos de solo lectura.