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

Quando você está pensando nos ciclos de vida dos Serviços Confiáveis do Azure Service Fabric, os conceitos básicos do ciclo de vida são os 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 ouvintes.
    • Todos os ouvintes retornados são abertos, permitindo a comunicação com o serviço.
    • O método RunAsync do serviço é chamado, permitindo que o serviço execute tarefas de longa duração ou trabalho em segundo plano.
  • Durante o encerramento:
    • O token de cancelamento passado para RunAsync é cancelado e os ouvintes são fechados.
    • Depois que os ouvintes fecham, o próprio objeto de serviço é destruído.

Há detalhes sobre a ordenação exata desses eventos. A ordem dos eventos pode mudar ligeiramente dependendo se o Serviço Confiável é stateless ou stateful. Além disso, para serviços com estado, devemos lidar com o cenário de swap primário. Durante essa sequência, a função de Primary é transferida para outra réplica (ou retorna) sem que o serviço seja desligado. Finalmente, devemos pensar em condições de erro ou falha.

Inicialização de 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 ouvintes retornados são abertos. ICommunicationListener.OpenAsync() é chamado a cada ouvinte.
  3. Então, em paralelo, duas coisas acontecem -
    • O método do StatelessService.RunAsync() serviço é chamado.
    • Se presente, o método do StatelessService.OnOpenAsync() serviço é chamado. Esta chamada é uma substituição incomum, mas está disponível. As tarefas de inicialização de serviço estendidas podem ser iniciadas neste momento.

Desligamento do serviço sem estado

Para encerrar um serviço sem estado, o mesmo padrão é seguido, exatamente no sentido inverso:

  1. Todos os ouvintes abertos são fechados. ICommunicationListener.CloseAsync() é chamado a cada ouvinte.
  2. O token de cancelamento passado para RunAsync() é cancelado. Uma verificação da propriedade do token IsCancellationRequested de cancelamento retorna true e, se chamado, o método do ThrowIfCancellationRequested token lança um OperationCanceledExceptionarquivo . O Service Fabric aguarda RunAsync() a conclusão.
  3. Após RunAsync() a conclusão, o método do StatelessService.OnCloseAsync() serviço é chamado, se presente. OnCloseAsync é chamado quando a instância de serviço sem estado será encerrada normalmente. Isso pode ocorrer quando o código do serviço está sendo atualizado, a instância de serviço está sendo movida devido ao balanceamento de carga ou uma falha transitória é detetada. É incomum substituir StatelessService.OnCloseAsync()o , mas ele pode ser usado para fechar recursos com segurança, interromper o processamento em segundo plano, terminar de salvar o estado externo ou fechar conexões existentes.
  4. Após StatelessService.OnCloseAsync() a conclusão, o objeto de serviço é destruído.

Inicialização de serviço com monitoraçã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 monitoração de estado, a ordem dos eventos é a seguinte:

  1. O serviço é construído.

  2. StatefulServiceBase.OnOpenAsync() é chamado. Essa chamada geralmente não é substituída no serviço.

  3. StatefulServiceBase.CreateServiceReplicaListeners() é invocado.

    • Se o serviço for um serviço Principal, todos os ouvintes retornados serão abertos. ICommunicationListener.OpenAsync() é chamado a cada ouvinte.
    • Se o serviço for um serviço Secundário, somente os ouvintes marcados como ListenOnSecondary = true serão abertos. Ter ouvintes abertos em secundárias é menos comum.
  4. Depois, em paralelo:

    • Se o serviço for atualmente um Primário, o método do StatefulServiceBase.RunAsync() serviço será chamado.
    • StatefulServiceBase.OnChangeRoleAsync() é chamado. Essa chamada geralmente não é substituída no serviço.

    Nota

    Para uma nova réplica secundária, StatefulServiceBase.OnChangeRoleAsync() é chamado duas vezes. Uma vez após o passo 2, quando se torna um secundário ocioso e novamente durante o passo 4, quando se torna um secundário ativo. Para obter mais informações sobre o ciclo de vida da réplica e da instância, leia Ciclo de vida da réplica e da instância.

Desligamento do serviço com estado

Como os serviços sem monitoração de estado, os eventos do ciclo de vida durante o desligamento são os mesmos que durante a inicialização, mas invertidos. Quando um serviço com monitoração de estado está sendo encerrado, ocorrem os seguintes eventos:

  1. Todos os ouvintes abertos são fechados. ICommunicationListener.CloseAsync() é chamado a cada ouvinte.

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

  3. O token de cancelamento passado para RunAsync() é cancelado. Uma verificação da propriedade do token IsCancellationRequested de cancelamento retorna true e, se chamado, o método do ThrowIfCancellationRequested token lança um OperationCanceledExceptionarquivo . O Service Fabric aguarda RunAsync() a conclusão.

    Nota

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

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

Serviço com estado Trocas primárias

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

Para a Primária que está rebaixada

Para a réplica principal que foi rebaixada, o Service Fabric precisa dessa réplica para interromper o processamento de mensagens e encerrar qualquer trabalho em segundo plano que esteja fazendo. Como resultado, essa etapa se parece com quando o serviço é encerrado. Uma diferença é que o serviço não é destruído ou fechado porque permanece como Secundário. As seguintes APIs são chamadas:

  1. Todos os ouvintes abertos são fechados. ICommunicationListener.CloseAsync() é chamado a cada ouvinte.
  2. O token de cancelamento passado para RunAsync() é cancelado. Uma verificação da propriedade do token IsCancellationRequested de cancelamento retorna true e, se chamado, o método do ThrowIfCancellationRequested token lança um OperationCanceledExceptionarquivo . O Service Fabric aguarda RunAsync() a conclusão.
  3. Os ouvintes marcados como ListenOnSecondary = true são abertos.
  4. O serviço StatefulServiceBase.OnChangeRoleAsync() é chamado. Essa chamada geralmente não é substituída no serviço.

Para o Secundário que é promovido

Da mesma forma, o Service Fabric precisa da réplica secundária promovida para começar a ouvir mensagens no fio e iniciar quaisquer tarefas em segundo plano que precise concluir. Como resultado, esse processo se parece com quando o serviço é criado, exceto que a réplica em si já existe. As seguintes APIs são chamadas:

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

Nota

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

Problemas comuns durante o desligamento do serviço com monitoração de estado e o rebaixamento primário

O Service Fabric altera o Primary de um serviço com monitoração de estado por vários motivos. Os mais comuns são o reequilíbrio de cluster e a atualização de aplicativos. Durante essas operações (bem como durante o desligamento normal do serviço, como você veria se o serviço foi excluído), é importante que o serviço respeite o CancellationToken.

Os serviços que não lidam com o cancelamento de forma limpa podem ter vários problemas. Essas operações são lentas porque o Service Fabric aguarda que os serviços parem normalmente. Isso pode, em última análise, levar a atualizações com falha que expiram 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 rebalanceados porque leva muito tempo para movê-los para outro lugar.

Como os serviços são stateful, também é provável que eles usem as Coleções Confiáveis. No Service Fabric, quando um primário é rebaixado, uma das primeiras coisas que acontece é que o acesso de gravação ao estado subjacente é revogado. Isso leva a um segundo conjunto de problemas que podem afetar o ciclo de vida do serviço. As coleções retornam exceções com base no tempo e se a réplica está sendo movida ou encerrada. Essas exceções devem ser tratadas corretamente. As exceções lançadas pelo Service Fabric se enquadram nas categorias permanente (FabricException) e transitória (FabricTransientException). As exceções permanentes devem ser registradas e lançadas, enquanto as exceções transitórias podem ser repetidas com base em alguma lógica de repetição.

Lidar com as exceções decorrentes do uso do em conjunto com eventos do ciclo de vida do ReliableCollections serviço é uma parte importante do teste e da validação de um Serviço Confiável. Recomendamos que você sempre execute seu serviço sob carga enquanto executa atualizações e testes de caos antes de implantar na produção. Estas etapas básicas ajudam a garantir que seu serviço seja implementado corretamente e manipule eventos do 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. Por exemplo, se o serviço faz todo o seu trabalho em resposta a chamadas de usuários, não há necessidade de implementar RunAsync(). Apenas os ouvintes de comunicação e seu código associado são necessários. Da mesma forma, criar e retornar ouvintes de comunicação é opcional, pois o serviço pode ter apenas trabalho em segundo plano para fazer e, portanto, só precisa implementar RunAsync().
  • É válido para que um serviço seja concluído RunAsync() com sucesso e retorne dele. Concluir não é uma condição de falha. A conclusão RunAsync() indica que o trabalho em segundo plano do serviço foi concluído. Para serviços confiáveis com monitoração de estado, é chamado novamente se a réplica for rebaixada de Primária para Secundária e, em seguida, RunAsync() promovida de volta para Primária.
  • Se um serviço sair lançando RunAsync() alguma exceção inesperada, isso constituirá uma falha. O objeto de serviço é desligado e um erro de integridade é relatado.
  • Embora não haja limite de tempo para retornar desses métodos, você perde imediatamente a capacidade de escrever em Coleções Confiáveis e, portanto, não pode concluir nenhum trabalho real. Recomendamos que você retorne o mais rápido possível após receber o pedido de cancelamento. Se o seu serviço não responder a essas chamadas de API em um período de tempo razoável, o Service Fabric poderá encerrar o serviço à força. Normalmente, isso só acontece durante atualizações de aplicativos ou quando um serviço está sendo excluído. Esse tempo limite é de 15 minutos por padrão.
  • Falhas no caminho resultam em OnAbort() ser chamado, o OnCloseAsync() que é uma oportunidade de melhor esforço para o serviço limpar e liberar quaisquer recursos que eles reivindicaram. Isso geralmente é chamado quando uma falha permanente é detetada no nó ou quando o Service Fabric não pode gerenciar de forma confiável o ciclo de vida da instância de serviço devido a falhas internas.
  • OnChangeRoleAsync() é chamado quando a réplica de serviço com monitoração de estado está mudando de função, por exemplo, para primária ou secundária. As réplicas primárias recebem status de gravação (têm permissão para criar e gravar em Coleções Confiáveis). As réplicas secundárias recebem status de leitura (só podem ser lidas a partir de Coleções Confiáveis existentes). A maior parte do trabalho em um serviço com monitoração de estado é executada na réplica principal. As réplicas secundárias podem executar validação somente leitura, geração de relatórios, mineração de dados ou outros trabalhos somente leitura.

Próximos passos