Compartilhar via


Ciclo de vida de Reliable Services

Os Reliable Services são um dos modelos de programação disponíveis no Microsoft Azure Service Fabric. Ao aprender sobre o ciclo de vida dos Reliable Services, o mais importante é entender os eventos de ciclo de vida básicos. A ordem exata de eventos depende dos detalhes de configuração.

Em geral, o ciclo de vida dos Reliable Services inclui os seguintes eventos:

  • Durante a inicialização:
    • Os serviços são construídos.
    • Os serviços têm a oportunidade de construir e retornar 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, possibilitando um serviço de longa execução ou trabalho em segundo plano.
  • Durante o desligamento:
    • O token de cancelamento passado para runAsync é cancelado e os ouvintes são fechados.
    • O objeto do serviço será destruído.

A ordem de eventos em Reliable Services pode ser ligeiramente alterada, dependendo se o Reliable Service é com ou sem estado.

Além disso, para serviços com estado, você deve solucionar o cenário de troca primária. Durante esta sequência, a função da Primária é transferida para outra réplica (ou retorna) sem o desligamento do serviço.

Por fim, você tem que pensar sobre as condições de erro ou falha.

Inicialização de serviço sem estado

O ciclo de vida de um serviço sem estado é bastante simples. Aqui está a ordem de eventos:

  1. O Serviço foi construído.
  2. StatelessService.createServiceInstanceListeners() é invocado e todos os ouvintes retornados são abertos. CommunicationListener.openAsync() é chamado em cada ouvinte.
  3. Em paralelo:
    • O método de serviço runAsync (StatelessService.runAsync()) é chamado.
    • Se estiver presente, o método onOpenAsync do próprio serviço será chamado. Especificamente, StatelessService.onOpenAsync() é chamado. Essa não é uma substituição comum, mas está disponível.

Desligamento de serviço sem estado

Ao desligar um serviço sem estado, o mesmo padrão é seguido, porém na ordem inversa:

  1. Todos os ouvintes abertos são fechados. CommunicationListener.closeAsync() é chamado em cada ouvinte.
  2. O token de cancelamento passado para runAsync() é cancelado. A verificação da propriedade isCancelled do token de cancelamento retorna true e, se chamado, o método throwIfCancellationRequested do token vai lançar CancellationException.
  3. Depois que runAsync() é concluído, o método StatelessService.onCloseAsync() do serviço é chamado, se estiver presente. Novamente, não é uma substituição comum, mas pode ser usada para fechar todos os recursos com segurança, interromper todos os processamentos em segundo plano, terminar de salvar o estado externo ou fechar conexões existentes.
  4. Depois que StatelessService.onCloseAsync() for concluído, o objeto de serviço será destruído.

Inicialização de serviço com estado

Os serviços com estado têm um padrão semelhante aos serviços sem estado, com algumas alterações. Veja a ordem de eventos para iniciar um serviço com estado:

  1. O Serviço foi construído.
  2. StatefulServiceBase.onOpenAsync() é chamado. Essa chamada não costuma ser substituída no serviço.
  3. StatefulServiceBase.createServiceReplicaListeners() é invocado.
    • Se o serviço for um serviço primário, todos os ouvintes retornados serão abertos. CommunicationListener.openAsync() é chamado em cada ouvinte.
    • Se o serviço for um serviço secundário, somente ouvintes marcados como listenOnSecondary = true serão abertos. Ter ouvintes abertos em secundários é menos comum.
  4. Em paralelo:
    • Se o serviço for primário no momento, o método StatefulServiceBase.runAsync() do serviço será chamado.
    • StatefulServiceBase.onChangeRoleAsync() é chamado. Essa chamada não costuma ser substituída no serviço.

Observação

Para uma nova réplica secundária, StatefulServiceBase.onChangeRoleAsync() é chamada duas vezes. Uma vez após a etapa 2, quando ela se torna uma secundária ociosa e novamente durante a etapa 4, quando ela se torna uma Secundária Ativa. Para obter mais informações sobre o ciclo de vida de réplica e instância, leia o Ciclo de Vida de Réplica e Instância.

Desligamento de serviço com estado

Da mesma forma que os serviços sem monitoração de estado, os eventos de ciclo de vida durante o desligamento são os mesmos que durante a inicialização, porém invertidos. Quando um serviço com estado está sendo desligado, ocorrem os seguintes eventos:

  1. Todos os ouvintes abertos são fechados. CommunicationListener.closeAsync() é chamado em cada ouvinte.
  2. O token de cancelamento passado para runAsync() é cancelado. Uma chamada para o método isCancelled() do token de cancelamento retorna true e, se chamado, o método throwIfCancellationRequested() do token lança um OperationCanceledException. Service Fabric aguarda runAsync() para a conclusão.

Observação

Esperar pela conclusão de runAsync só é necessário se essa réplica for uma réplica primária.

  1. Após runAsync() terminar, o método StatefulServiceBase.onCloseAsync() do serviço será chamado. Essa chamada não é uma substituição comum, mas está disponível.
  2. Depois que StatefulServiceBase.onCloseAsync() for concluído, o objeto de serviço será destruído.

Trocas de primária do serviço com estado

Durante a execução de um serviço com estado, os ouvintes de comunicação são abertos e o método runAsync só é chamado para as réplicas primárias daqueles serviços com estado. Réplicas secundárias são construídas, mas não veem mais chamadas. Durante a execução de um serviço com estado, a réplica atualmente primária pode alterar. Os eventos de ciclo de vida que uma réplica com monitoração de estado pode ver depende se ela é a réplica que está sendo rebaixada ou promovida durante a troca.

Para a réplica primária rebaixada

O Service Fabric precisa da réplica primária que é rebaixada para parar o processamento de mensagens e parar qualquer trabalho em segundo plano. Esta etapa é semelhante a quando o serviço for desligado. Uma diferença é que o Serviço não é destruído nem fechado, pois ele permanece como Secundário. Os seguintes eventos ocorrem:

  1. Todos os ouvintes abertos são fechados. CommunicationListener.closeAsync() é chamado em cada ouvinte.
  2. O token de cancelamento passado para runAsync() é cancelado. Uma verificação de que o método isCancelled() do token de cancelamento retorna true. Se chamado, método throwIfCancellationRequested() do token lança um OperationCanceledException. Service Fabric aguarda runAsync() para a conclusão.
  3. Ouvintes marcados como listenOnSecondary = true são abertos.
  4. O serviço StatefulServiceBase.onChangeRoleAsync() é chamado. Essa chamada não costuma ser substituída no serviço.

Para a réplica secundária promovida

Da mesma forma, o Service Fabric precisa que a réplica secundária promovida escute mensagens na transmissão e inicie quaisquer tarefas em segundo plano que precise concluir. Esta etapa é semelhante a quando o serviço é criado. A diferença é que a réplica em si já existe. Os seguintes eventos ocorrem:

  1. CommunicationListener.closeAsync() é chamado para todos os ouvintes abertos (marcado com listenOnSecondary = true)
  2. Todos os ouvintes de comunicação são abertos. CommunicationListener.openAsync() é chamado em cada ouvinte.
  3. Em paralelo:
    • O método StatefulServiceBase.runAsync() do serviço é chamado.
    • StatefulServiceBase.onChangeRoleAsync() é chamado. Essa chamada não costuma ser substituída no serviço.

Observação

createServiceReplicaListeners é chamado apenas uma vez e não é chamado novamente durante o processo de promoção ou rebaixamento de réplica; as mesmas ServiceReplicaListener instâncias são usadas, mas novas CommunicationListener 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 estado e rebaixamento do primário

O Service Fabric altera a réplica primária de um serviço com estado por vários motivos. Os mais comuns são rebalanceamento do cluster e upgrade de aplicativo. Durante essas operações, é importante que o serviço respeite o cancellationToken. Isso também se aplica durante o desligamento normal do serviço, como se o serviço fosse excluído.

Os serviços que não tratam o cancelamento corretamente podem enfrentar vários problemas. Essas operações são lentas porque o Service Fabric aguarda até que os serviços parem normalmente. Em última instância, isso leva a falhas de upgrade que atingem um tempo limite e são revertidas. Falha em cumprir o token de cancelamento também pode causar clusters desequilibrados. Os clusters ficam desequilibrados porque os nós ficam quentes. No entanto, os serviços não podem ser reequilibrados porque demora muito para movê-los para outro lugar.

Uma vez que os serviços têm estado, também é provável que eles usem Coleções Confiáveis. No Service Fabric, quando uma réplica primária é rebaixada, 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 pode afetar o ciclo de vida do serviço. As coleções retornam exceções que se baseiam no tempo e em se a réplica está sendo movida ou desligada. É importante tratar essas exceções corretamente.

Exceções geradas pelo Service Fabric são permanentes (FabricException) ou transitórias (FabricTransientException). As exceções permanentes devem ser registradas e lançadas. As exceções transitórias podem ser repetidas com base na lógica de repetição.

Uma parte importante de testar e validar os Reliable Services é manipular as exceções que vêm do uso de ReliableCollections em conjunto com eventos de ciclo de vida do serviço. É recomendável que você sempre execute seu serviço sob carga. Você também deve executar atualizações e teste de caos antes de implantar para produção. Essas etapas básicas ajudam a garantir que o serviço seja implementado corretamente,e que ele trate os eventos do ciclo de vida corretamente.

Observações sobre o ciclo de vida do serviço

  • Tanto o método runAsync() quanto as chamadas createServiceInstanceListeners/createServiceReplicaListeners são opcionais. Um serviço pode ter um, ambos ou nenhum. Por exemplo, se o serviço fizer todo seu trabalho em resposta a chamadas do usuário, não será necessário 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. O serviço pode ter somente trabalho em segundo plano para fazer, e portanto precisa implementar runAsync().
  • Isso é válido para um serviço concluir runAsync() com êxito e retornar dele. Isso não é considerado uma condição de falha. Representa o trabalho em segundo plano da finalização do serviço. Para serviço confiável com estado, runAsync() seria chamado novamente se o serviço tiver sido rebaixado de primário e promovido novamente para primário.
  • Se um serviço sair de runAsync(), lançando uma exceção inesperada, isso constituirá uma falha. O objeto de serviço é desligado e um erro de integridade é reportado.
  • Embora não haja um limite de tempo para o retorno desses métodos, você perde imediatamente a capacidade de gravar. Portanto, não pode concluir nenhum trabalho real. Recomendamos que você retorne o mais rápido possível após o recebimento da solicitação de cancelamento. Se o serviço não responder a essas chamadas à API dentro de um período razoável, o Service Fabric poderá forçar o encerramento do serviço. Geralmente isso ocorre apenas durante atualizações de aplicativo ou quando um serviço está sendo excluído. Esse tempo limite é de 15 minutos por padrão.
  • Falhas no caminho onCloseAsync() faz com que onAbort() seja chamado. Essa chamada é uma oportunidade de melhor esforço de última chance para o serviço ser limpo e liberar quaisquer recursos ocupados. Ele geralmente é chamado quando é detectada uma falha permanente no nó ou quando a malha de serviço não pode gerenciar confiavelmente o ciclo de vida da instância do serviço devido a falhas internas.
  • OnChangeRoleAsync() é chamado quando a réplica de serviço com estado está alterando funções, por exemplo para primário ou secundário. Réplicas primárias recebem status de gravação (têm permissão para criar as Coleções Confiáveis e gravar nelas). Réplicas secundárias recebem status de leitura (podem somente ler das coleções confiáveis existentes). A maior parte do trabalho em um serviço com estado é executado na réplica primária. Réplicas secundárias podem realizar validação somente leitura, geração de relatórios, mineração de dados ou outros trabalhos somente leitura.

Próximas etapas