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.
- O token de cancelamento passado para
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:
- O Serviço foi construído.
StatelessService.createServiceInstanceListeners()
é invocado e todos os ouvintes retornados são abertos.CommunicationListener.openAsync()
é chamado em cada ouvinte.- 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.
- O método de serviço
Desligamento de serviço sem estado
Ao desligar um serviço sem estado, o mesmo padrão é seguido, porém na ordem inversa:
- Todos os ouvintes abertos são fechados.
CommunicationListener.closeAsync()
é chamado em cada ouvinte. - O token de cancelamento passado para
runAsync()
é cancelado. A verificação da propriedadeisCancelled
do token de cancelamento retornatrue
e, se chamado, o métodothrowIfCancellationRequested
do token vai lançarCancellationException
. - Depois que
runAsync()
é concluído, o métodoStatelessService.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. - 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:
- O Serviço foi construído.
StatefulServiceBase.onOpenAsync()
é chamado. Essa chamada não costuma ser substituída no serviço.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.
- Se o serviço for um serviço primário, todos os ouvintes retornados serão abertos.
- 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.
- Se o serviço for primário no momento, o método
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:
- Todos os ouvintes abertos são fechados.
CommunicationListener.closeAsync()
é chamado em cada ouvinte. - O token de cancelamento passado para
runAsync()
é cancelado. Uma chamada para o métodoisCancelled()
do token de cancelamento retornatrue
e, se chamado, o métodothrowIfCancellationRequested()
do token lança umOperationCanceledException
. Service Fabric aguardarunAsync()
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.
- Após
runAsync()
terminar, o métodoStatefulServiceBase.onCloseAsync()
do serviço será chamado. Essa chamada não é uma substituição comum, mas está disponível. - 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:
- Todos os ouvintes abertos são fechados.
CommunicationListener.closeAsync()
é chamado em cada ouvinte. - O token de cancelamento passado para
runAsync()
é cancelado. Uma verificação de que o métodoisCancelled()
do token de cancelamento retornatrue
. Se chamado, métodothrowIfCancellationRequested()
do token lança umOperationCanceledException
. Service Fabric aguardarunAsync()
para a conclusão. - Ouvintes marcados como listenOnSecondary = true são abertos.
- 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:
CommunicationListener.closeAsync()
é chamado para todos os ouvintes abertos (marcado com listenOnSecondary = true)- Todos os ouvintes de comunicação são abertos.
CommunicationListener.openAsync()
é chamado em cada ouvinte. - 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.
- O método
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 chamadascreateServiceInstanceListeners/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 implementarrunAsync()
. 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 implementarrunAsync()
. - 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 queonAbort()
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.