Descrição geral do ciclo de vida do Reliable Services

Quando estiver a pensar nos ciclos de vida do Azure Service Fabric Reliable Services, as noções básicas do ciclo de vida são as mais importantes. Em geral, o ciclo de vida inclui o seguinte:

  • Durante o arranque:
    • Os serviços são construídos.
    • Os serviços têm a oportunidade de construir e devolver zero ou mais serviços de escuta.
    • Todos os serviços de escuta devolvidos são abertos, permitindo a comunicação com o serviço.
    • O método RunAsync do serviço é chamado, permitindo ao serviço realizar tarefas de execução prolongada ou trabalho em segundo plano.
  • Durante o encerramento:
    • O token de cancelamento transmitido para RunAsync é cancelado e os serviços de escuta são fechados.
    • Depois de os serviços de escuta fecharem, o objeto de serviço em si é desconstruído.

Existem detalhes sobre a ordenação exata destes eventos. A ordem dos eventos pode mudar ligeiramente consoante o Reliable Service esteja sem estado ou com monitorização de estado. Além disso, para serviços com monitorização de estado, temos de lidar com o cenário de troca primária. Durante esta sequência, a função Primária é transferida para outra réplica (ou volta) sem que o serviço seja encerrado. Por fim, temos de pensar nas condições de erro ou falha.

Arranque do serviço sem estado

O ciclo de vida de um serviço sem estado é simples. Eis a ordem dos eventos:

  1. O serviço é construído.
  2. StatelessService.CreateServiceInstanceListeners() é invocado e todos os serviços de escuta devolvidos são abertos. ICommunicationListener.OpenAsync() é chamado em cada serviço de escuta.
  3. Em seguida, em paralelo, duas coisas acontecem -
    • O método do StatelessService.RunAsync() serviço é chamado.
    • Se estiver presente, o método do StatelessService.OnOpenAsync() serviço é chamado. Esta chamada é uma substituição invulgar, mas está disponível. Neste momento, as tarefas de inicialização de serviços alargados podem ser iniciadas.

Encerramento do serviço sem estado

Para encerrar um serviço sem estado, é seguido o mesmo padrão, ao contrário:

  1. Todos os serviços de escuta abertos são fechados. ICommunicationListener.CloseAsync() é chamado em cada serviço de escuta.
  2. O token de cancelamento transmitido para RunAsync() é cancelado. Uma verificação da propriedade do token de IsCancellationRequested cancelamento devolve true e, se for chamado, o método do ThrowIfCancellationRequested token gera um OperationCanceledException. O Service Fabric aguarda pela RunAsync() conclusão.
  3. Após RunAsync() a conclusão, o método do StatelessService.OnCloseAsync() serviço é chamado, se estiver presente. OnCloseAsync é chamado quando a instância de serviço sem estado vai ser encerrada corretamente. Isto pode ocorrer quando o código do serviço está a ser atualizado, a instância de serviço está a ser movida devido ao balanceamento de carga ou é detetada uma falha transitória. Não é comum substituir StatelessService.OnCloseAsync(), mas pode ser utilizado para fechar recursos em segurança, parar o processamento em segundo plano, terminar de guardar o estado externo ou fechar as ligações existentes.
  4. Após StatelessService.OnCloseAsync() a conclusão, o objeto de serviço é destruído.

Arranque do serviço com monitorização de estado

Os serviços com estado têm um padrão semelhante aos serviços sem estado, com algumas alterações. Para iniciar um serviço com estado, a ordem dos eventos é a seguinte:

  1. O serviço é construído.

  2. StatefulServiceBase.OnOpenAsync() é chamado. Normalmente, esta chamada não é substituída no serviço.

  3. StatefulServiceBase.CreateServiceReplicaListeners() é invocado.

    • Se o serviço for um serviço Primário, todos os serviços de escuta devolvidos serão abertos. ICommunicationListener.OpenAsync() é chamado em cada serviço de escuta.
    • Se o serviço for um serviço Secundário, apenas os serviços de escuta marcados como ListenOnSecondary = true são abertos. Ter serviços de escuta abertos em secundários é menos comum.
  4. Em seguida, em paralelo:

    • Se o serviço for atualmente primário, o método do StatefulServiceBase.RunAsync() serviço é chamado.
    • StatefulServiceBase.OnChangeRoleAsync() é chamado. Normalmente, esta chamada não é substituída no serviço.

    Nota

    Para uma nova réplica secundária, StatefulServiceBase.OnChangeRoleAsync() é chamada duas vezes. Uma vez após o passo 2, quando se torna um Secundário Inativo e novamente durante o passo 4, quando se torna um Active Secondary. Para obter mais informações sobre o ciclo de vida da réplica e da instância, leia Replica and Instance Lifecycle (Ciclo de Vida da Réplica e da Instância).

Encerramento do serviço com monitorização de estado

Tal como os serviços sem estado, os eventos de ciclo de vida durante o encerramento são os mesmos que durante o arranque, mas invertidos. Quando um serviço com estado está a ser encerrado, ocorrem os seguintes eventos:

  1. Todos os serviços de escuta abertos são fechados. ICommunicationListener.CloseAsync() é chamado em cada serviço de escuta.

  2. StatefulServiceBase.OnCloseAsync() o método é chamado. Esta chamada é uma substituição invulgar, mas está disponível.

  3. O token de cancelamento transmitido para RunAsync() é cancelado. Uma verificação da propriedade do token de IsCancellationRequested cancelamento devolve true e, se for chamado, o método do ThrowIfCancellationRequested token gera um OperationCanceledException. O Service Fabric aguarda pela RunAsync() conclusão.

    Nota

    A necessidade de aguardar a conclusão de RunAsync só é necessária se esta réplica for uma Réplica primária.

  4. Após StatefulServiceBase.RunAsync() a conclusão, o objeto de serviço é destruído.

Trocas principais de serviço com monitorização de estado

Enquanto um serviço com monitorização de estado está em execução, apenas as Réplicas primárias desses serviços com monitorização de estado têm os serviços de escuta de comunicação abertos e o respetivo método RunAsync chamado. As réplicas secundárias são construídas, mas não vê mais chamadas. Enquanto um serviço com monitorização de estado está em execução, a réplica que é atualmente a Primária pode ser alterada em resultado da otimização do balanceamento de cluster ou falha. O que significa isto em termos dos eventos de ciclo de vida que uma réplica pode ver? O comportamento que a réplica com monitorização de estado vê depende se é a réplica a ser despromoviada ou promovida durante a troca.

Para a Primária que é despromoviada

Para a Réplica primária que é despromoviada, o Service Fabric precisa desta réplica para parar de processar mensagens e sair de qualquer trabalho em segundo plano que esteja a fazer. Como resultado, este passo parece ter sido quando o serviço foi encerrado. Uma diferença é que o serviço não é desconstruído ou fechado porque permanece como secundário. As seguintes APIs são chamadas:

  1. Todos os serviços de escuta abertos são fechados. ICommunicationListener.CloseAsync() é chamado em cada serviço de escuta.
  2. O token de cancelamento transmitido para RunAsync() é cancelado. Uma verificação da propriedade do token de IsCancellationRequested cancelamento devolve true e, se for chamado, o método do ThrowIfCancellationRequested token gera um OperationCanceledException. O Service Fabric aguarda pela RunAsync() conclusão.
  3. Os serviços de escuta marcados como ListenOnSecondary = true são abertos.
  4. O serviço StatefulServiceBase.OnChangeRoleAsync() é chamado. Normalmente, esta chamada não é substituída no serviço.

Para a Secundária que é promovida

Da mesma forma, o Service Fabric precisa da réplica secundária que é promovida para começar a escutar mensagens na transmissão e iniciar quaisquer tarefas em segundo plano que precise de concluir. Como resultado, este processo parece ter sido feito quando o serviço foi criado, exceto que a réplica em si já existe. As seguintes APIs são chamadas:

  1. ICommunicationListener.CloseAsync() é chamado para todos os serviços de escuta abertos (marcado com ListenOnSecondary = true).
  2. Todos os serviços de escuta de comunicação são abertos. ICommunicationListener.OpenAsync() é chamado a cada serviço de escuta.
  3. Em seguida, em paralelo:
    • O método do StatefulServiceBase.RunAsync() serviço é chamado.
    • StatefulServiceBase.OnChangeRoleAsync() é chamado. Esta chamada não é geralmente substituída no serviço.

Nota

CreateServiceReplicaListeners é chamado apenas uma vez e não é chamado novamente durante o processo de promoção ou despromoção da réplica; as mesmas ServiceReplicaListener instâncias são utilizadas, mas são criadas novas ICommunicationListener instâncias (chamando o ServiceReplicaListener.CreateCommunicationListener método) depois de as instâncias anteriores serem fechadas.

Problemas comuns durante o encerramento do serviço com estado e despromoção primária

O Service Fabric altera o Principal de um serviço com estado por vários motivos. Os mais comuns são o reequilíbrio do cluster e aatualização da aplicação. Durante estas operações (bem como durante o encerramento normal do serviço, como veria se o serviço foi eliminado), é importante que o serviço respeite o CancellationToken.

Os serviços que não processam o cancelamento de forma limpa podem ter vários problemas. Estas operações são lentas porque o Service Fabric aguarda que os serviços parem corretamente. Isto pode, em última análise, levar a atualizações falhadas que excedem o tempo limite e revertem. O não cumprimento do token de cancelamento também pode causar clusters desequilibrados. Os clusters ficam desequilibrados porque os nós ficam quentes, mas os serviços não podem ser reequilibrados porque demora muito tempo a movê-los para outro local.

Uma vez que os serviços têm estado, também é provável que utilizem as Coleções Fiáveis. No Service Fabric, quando uma Primária é despromoviada, uma das primeiras coisas que acontece é que o acesso de escrita ao estado subjacente é revogado. Isto leva a um segundo conjunto de problemas que podem afetar o ciclo de vida do serviço. As coleções devolvem exceções com base na temporização e se a réplica está a ser movida ou encerrada. Estas exceções devem ser processadas corretamente. As exceções emitidas pelo Service Fabric enquadram-se em categorias permanentes (FabricException) e transitórias (FabricTransientException). As exceções permanentes devem ser registadas e emitidas enquanto as exceções transitórias podem ser repetidas com base em alguma lógica de repetição.

Lidar com as exceções provenientes da utilização do ReliableCollections em conjunto com os eventos de ciclo de vida do serviço é uma parte importante do teste e validação de um Reliable Service. Recomendamos que execute sempre o seu serviço sob carga durante a realização de atualizações e testes de caos antes de implementar na produção. Estes passos básicos ajudam a garantir que o seu serviço está corretamente implementado e processa os eventos de ciclo de vida corretamente.

Notas sobre o ciclo de vida do serviço

  • Tanto o RunAsync() método como as CreateServiceReplicaListeners/CreateServiceInstanceListeners chamadas são opcionais. Um serviço pode ter um deles, ambos ou nenhum deles. Por exemplo, se o serviço fizer todo o seu trabalho em resposta a chamadas de utilizador, não é necessário implementar RunAsync(). Apenas os serviços de escuta de comunicação e o respetivo código associado são necessários. Da mesma forma, criar e devolver serviços de escuta de comunicação é opcional, uma vez que o serviço só pode ter trabalho em segundo plano para fazer, pelo que só precisa de implementar RunAsync().
  • É válido para que um serviço seja concluído RunAsync() com êxito e seja devolvido a partir do mesmo. Concluir não é uma condição de falha. RunAsync() A conclusão indica que o trabalho em segundo plano do serviço foi concluído. Para serviços fiáveis com estado, RunAsync() é chamado novamente se a réplica for despromoviada de Primária para Secundária e, em seguida, promovida de volta para Primária.
  • Se um serviço sair ao RunAsync() lançar alguma exceção inesperada, tal constitui uma falha. O objeto de serviço é encerrado e é comunicado um erro de estado de funcionamento.
  • Embora não exista um limite de tempo para regressar destes métodos, perde imediatamente a capacidade de escrever em Reliable Collections e, por conseguinte, não pode concluir nenhum trabalho real. Recomendamos que devolva o mais rapidamente possível ao receber o pedido de cancelamento. Se o seu serviço não responder a estas chamadas à API num período de tempo razoável, o Service Fabric pode terminar o serviço à força. Normalmente, isto só acontece durante as atualizações da aplicação ou quando um serviço está a ser eliminado. Por predefinição, este tempo limite é de 15 minutos.
  • As falhas no caminho resultam na OnCloseAsync()OnAbort() chamada, que é uma oportunidade de melhor esforço de última oportunidade para o serviço limpar e libertar quaisquer recursos que tenham reclamado. Geralmente, isto é chamado quando é detetada uma falha permanente no nó ou quando o Service Fabric não consegue gerir de forma fiável o ciclo de vida da instância de serviço devido a falhas internas.
  • OnChangeRoleAsync() é chamada quando a réplica de serviço com estado está a mudar de função, por exemplo, para primária ou secundária. As réplicas primárias recebem o estado de escrita (têm permissão para criar e escrever em Reliable Collections). As réplicas secundárias recebem o estado de leitura (só podem ser lidas a partir de Coleções Fiáveis existentes). A maioria do trabalho num serviço com estado é efetuada na réplica primária. As réplicas secundárias podem executar validação só de leitura, geração de relatórios, extração de dados ou outras tarefas só de leitura.

Passos seguintes