Resolver problemas da atualização da aplicação

Este artigo aborda alguns dos problemas comuns relacionados com a atualização de uma aplicação do Azure Service Fabric e como resolvê-las.

Resolver problemas de uma atualização da aplicação com falhas

Quando uma atualização falha, o resultado do comando Get-ServiceFabricApplicationUpgrade contém informações adicionais para depurar a falha. A lista seguinte especifica como as informações adicionais podem ser utilizadas:

  1. Identifique o tipo de falha.
  2. Identifique o motivo da falha.
  3. Isole um ou mais componentes com falhas para uma investigação mais aprofundada.

Estas informações estão disponíveis quando o Service Fabric deteta a falha, independentemente de a FailureAction ser para reverter ou suspender a atualização.

Identificar o tipo de falha

Na saída de Get-ServiceFabricApplicationUpgrade, FailureTimestampUtc identifica o carimbo de data/hora (em UTC) no qual foi detetada uma falha de atualização pelo Service Fabric e a FailureAction foi acionada. FailureReason identifica uma das três potenciais causas de alto nível da falha:

  1. UpgradeDomainTimeout - Indica que um domínio de atualização específico demorou demasiado tempo a ser concluído e UpgradeDomainTimeout expirou.
  2. OverallUpgradeTimeout - Indica que a atualização geral demorou demasiado tempo a ser concluída e UpgradeTimeout expirou.
  3. HealthCheck - Indica que após atualizar um domínio de atualização, a aplicação permaneceu em mau estado de funcionamento de acordo com as políticas de estado de funcionamento especificadas e HealthCheckRetryTimeout expirou.

Estas entradas só aparecem no resultado quando a atualização falha e começa a reverter. São apresentadas mais informações consoante o tipo de falha.

Investigar tempos limite de atualização

As falhas de tempo limite da atualização são normalmente causadas por problemas de disponibilidade do serviço. A saída que se segue a este parágrafo é típica das atualizações em que as réplicas de serviço ou as instâncias não iniciam na nova versão de código. O campo UpgradeDomainProgressAtFailure captura um instantâneo de qualquer trabalho de atualização pendente no momento da falha.

Get-ServiceFabricApplicationUpgrade fabric:/DemoApp
ApplicationName                : fabric:/DemoApp
ApplicationTypeName            : DemoAppType
TargetApplicationTypeVersion   : v2
ApplicationParameters          : {}
StartTimestampUtc              : 4/14/2015 9:26:38 PM
FailureTimestampUtc            : 4/14/2015 9:27:05 PM
FailureReason                  : UpgradeDomainTimeout
UpgradeDomainProgressAtFailure : MYUD1

                                 NodeName            : Node4
                                 UpgradePhase        : PostUpgradeSafetyCheck
                                 PendingSafetyChecks :
                                     WaitForPrimaryPlacement - PartitionId: 744c8d9f-1d26-417e-a60e-cd48f5c098f0

                                 NodeName            : Node1
                                 UpgradePhase        : PostUpgradeSafetyCheck
                                 PendingSafetyChecks :
                                     WaitForPrimaryPlacement - PartitionId: 4b43f4d8-b26b-424e-9307-7a7a62e79750
UpgradeState                   : RollingBackCompleted
UpgradeDuration                : 00:00:46
CurrentUpgradeDomainDuration   : 00:00:00
NextUpgradeDomain              :
UpgradeDomainsStatus           : { "MYUD1" = "Completed";
                                 "MYUD2" = "Completed";
                                 "MYUD3" = "Completed" }
UpgradeKind                    : Rolling
RollingUpgradeMode             : UnmonitoredAuto
ForceRestart                   : False
UpgradeReplicaSetCheckTimeout  : 00:00:00

Neste exemplo, a atualização falhou no domínio de atualização MYUD1 e duas partições (744c8d9f-1d26-417e-a60e-cd48f5c098f0 e 4b43f4d8-b26b-424e-9307-7a7a62e79750) ficaram bloqueadas. As partições ficaram bloqueadas porque o runtime não conseguiu colocar réplicas primárias (WaitForPrimaryPlacement) nos nós de destino Node1 e Node4.

O comando Get-ServiceFabricNode pode ser utilizado para verificar se estes dois nós estão no domínio de atualização MYUD1. O UpgradePhase diz PostUpgradeSafetyCheck, o que significa que estas verificações de segurança estão a ocorrer depois de todos os nós no domínio de atualização terem terminado a atualização. Todas estas informações apontam para um potencial problema com a nova versão do código da aplicação. Os problemas mais comuns são erros de serviço na abertura ou promoção para caminhos de código primários.

Um UpgradePhase de PreUpgradeSafetyCheck significa que houve problemas ao preparar o domínio de atualização antes de ser executado. Os problemas mais comuns neste caso são erros de serviço no fecho ou despromoção dos caminhos de código primário.

O UpgradeState atual é RollingBackCompleted, pelo que a atualização original deve ter sido efetuada com uma Reversão FailureAction, que reverte automaticamente a atualização após a falha. Se a atualização original tiver sido efetuada com uma FailureAction manual, a atualização estará, em vez disso, num estado suspenso para permitir a depuração em direto da aplicação.

Em casos raros, o campo UpgradeDomainProgressAtFailure pode estar vazio se a atualização geral exceder o limite de tempo, assim como o sistema concluir todo o trabalho para o domínio de atualização atual. Se isto acontecer, experimente aumentar os valores dos parâmetros upgradeTimeout e UpgradeDomainTimeout e repita a atualização.

Investigar falhas de verificação de estado de funcionamento

As falhas de verificação de estado de funcionamento podem ser acionadas por vários problemas que podem ocorrer depois de todos os nós num domínio de atualização concluirem a atualização e passarem todas as verificações de segurança. O resultado seguinte a este parágrafo é típico de uma falha de atualização devido a verificações de estado de funcionamento falhadas. O campo UnhealthyEvaluations captura um instantâneo das verificações de estado de funcionamento que falharam no momento da atualização de acordo com a política de estado de funcionamento especificada.

Get-ServiceFabricApplicationUpgrade fabric:/DemoApp
ApplicationName                         : fabric:/DemoApp
ApplicationTypeName                     : DemoAppType
TargetApplicationTypeVersion            : v4
ApplicationParameters                   : {}
StartTimestampUtc                       : 4/24/2015 2:42:31 AM
UpgradeState                            : RollingForwardPending
UpgradeDuration                         : 00:00:27
CurrentUpgradeDomainDuration            : 00:00:27
NextUpgradeDomain                       : MYUD2
UpgradeDomainsStatus                    : { "MYUD1" = "Completed";
                                          "MYUD2" = "Pending";
                                          "MYUD3" = "Pending" }
UnhealthyEvaluations                    :
                                          Unhealthy services: 50% (2/4), ServiceType='PersistedServiceType', MaxPercentUnhealthyServices=0%.

                                          Unhealthy service: ServiceName='fabric:/DemoApp/Svc3', AggregatedHealthState='Error'.

                                              Unhealthy partitions: 100% (1/1), MaxPercentUnhealthyPartitionsPerService=0%.

                                              Unhealthy partition: PartitionId='3a9911f6-a2e5-452d-89a8-09271e7e49a8', AggregatedHealthState='Error'.

                                                  Error event: SourceId='Replica', Property='InjectedFault'.

                                          Unhealthy service: ServiceName='fabric:/DemoApp/Svc2', AggregatedHealthState='Error'.

                                              Unhealthy partitions: 100% (1/1), MaxPercentUnhealthyPartitionsPerService=0%.

                                              Unhealthy partition: PartitionId='744c8d9f-1d26-417e-a60e-cd48f5c098f0', AggregatedHealthState='Error'.

                                                  Error event: SourceId='Replica', Property='InjectedFault'.

UpgradeKind                             : Rolling
RollingUpgradeMode                      : Monitored
FailureAction                           : Manual
ForceRestart                            : False
UpgradeReplicaSetCheckTimeout           : 49710.06:28:15
HealthCheckWaitDuration                 : 00:00:00
HealthCheckStableDuration               : 00:00:10
HealthCheckRetryTimeout                 : 00:00:10
UpgradeDomainTimeout                    : 10675199.02:48:05.4775807
UpgradeTimeout                          : 10675199.02:48:05.4775807
ConsiderWarningAsError                  :
MaxPercentUnhealthyPartitionsPerService :
MaxPercentUnhealthyReplicasPerPartition :
MaxPercentUnhealthyServices             :
MaxPercentUnhealthyDeployedApplications :
ServiceTypeHealthPolicyMap              :

Investigar as falhas de verificação de estado de funcionamento requer primeiro uma compreensão do modelo de estado de funcionamento do Service Fabric. Mas mesmo sem uma compreensão tão aprofundada, podemos ver que dois serviços estão em mau estado de funcionamento: recursos de infraestrutura:/DemoApp/Svc3 e recursos de infraestrutura:/DemoApp/Svc2, juntamente com os relatórios de estado de funcionamento de erros ("InjectedFault" neste caso). Neste exemplo, dois em cada quatro serviços estão em mau estado de funcionamento, o que está abaixo do objetivo predefinido de 0% em mau estado de funcionamento (MaxPercentUnhealthyServices).

A atualização foi suspensa após a falha ao especificar uma FalhaAção do manual ao iniciar a atualização. Este modo permite-nos investigar o sistema em direto no estado com falhas antes de efetuar qualquer ação adicional.

Recuperar de uma atualização suspensa

Com uma reversão FailureAction, não é necessária nenhuma recuperação, uma vez que a atualização é revertida automaticamente após a falha. Com uma FailureAction manual, existem várias opções de recuperação:

  1. acionar uma reversão
  2. Prosseguir com o resto da atualização manualmente
  3. Retomar a atualização monitorizada

O comando Start-ServiceFabricApplicationRollback pode ser utilizado em qualquer altura para começar a reverter a aplicação. Assim que o comando for devolvido com êxito, o pedido de reversão foi registado no sistema e é iniciado pouco depois.

O comando Resume-ServiceFabricApplicationUpgrade pode ser utilizado para prosseguir com o resto da atualização manualmente, um domínio de atualização de cada vez. Neste modo, apenas as verificações de segurança são efetuadas pelo sistema. Não são efetuadas mais verificações de estado de funcionamento. Este comando só pode ser utilizado quando o UpgradeState mostrar RollingForwardPending, o que significa que o domínio de atualização atual terminou a atualização, mas o seguinte não foi iniciado (pendente).

O comando Update-ServiceFabricApplicationUpgrade pode ser utilizado para retomar a atualização monitorizada, com as verificações de segurança e de estado de funcionamento a serem efetuadas.

Update-ServiceFabricApplicationUpgrade fabric:/DemoApp -UpgradeMode Monitored
UpgradeMode                             : Monitored
ForceRestart                            :
UpgradeReplicaSetCheckTimeout           :
FailureAction                           :
HealthCheckWaitDuration                 :
HealthCheckStableDuration               :
HealthCheckRetryTimeout                 :
UpgradeTimeout                          :
UpgradeDomainTimeout                    :
ConsiderWarningAsError                  :
MaxPercentUnhealthyPartitionsPerService :
MaxPercentUnhealthyReplicasPerPartition :
MaxPercentUnhealthyServices             :
MaxPercentUnhealthyDeployedApplications :
ServiceTypeHealthPolicyMap              :

A atualização continua a partir do domínio de atualização onde foi suspensa pela última vez e utiliza os mesmos parâmetros de atualização e políticas de estado de funcionamento que anteriormente. Se necessário, qualquer um dos parâmetros de atualização e as políticas de estado de funcionamento apresentados na saída anterior podem ser alterados no mesmo comando quando a atualização for retomada. Neste exemplo, a atualização foi retomada no modo Monitorizado, com os parâmetros e as políticas de estado de funcionamento inalterados.

Resolver mais problemas

O Service Fabric não está a seguir as políticas de estado de funcionamento especificadas

Causa Possível 1:

O Service Fabric traduz todas as percentagens em números reais de entidades (por exemplo, réplicas, partições e serviços) para avaliação de estado de funcionamento e arredonda sempre para entidades inteiras. Por exemplo, se maxPercentUnhealthyReplicasPerPartition máximo for de 21% e existirem cinco réplicas, o Service Fabric permite até duas réplicas em mau estado de funcionamento (ou seja,Math.Ceiling (5*0.21) ). Assim, as políticas de saúde devem ser definidas em conformidade.

Causa Possível 2:

As políticas de estado de funcionamento são especificadas em termos de percentagens do total de serviços e não de instâncias de serviço específicas. Por exemplo, antes de uma atualização, se uma aplicação tiver quatro instâncias de serviço A, B, C e D, em que o serviço D está em mau estado de funcionamento, mas com pouco impacto na aplicação. Queremos ignorar o serviço D em mau estado de funcionamento conhecido durante a atualização e definir o parâmetro MaxPercentUnhealthyServices como 25%, assumindo que apenas A, B e C precisam de estar em bom estado de funcionamento.

No entanto, durante a atualização, D pode ficar em bom estado de funcionamento enquanto C fica em mau estado de funcionamento. A atualização continuaria a ser bem-sucedida porque apenas 25% dos serviços estão em mau estado de funcionamento. No entanto, pode resultar em erros inesperados devido a C estar inesperadamente em mau estado de funcionamento em vez de D. Nesta situação, D deve ser modelado como um tipo de serviço diferente de A, B e C. Uma vez que as políticas de estado de funcionamento são especificadas por tipo de serviço, podem ser aplicados diferentes limiares de percentagem de mau estado de funcionamento a diferentes serviços.

Não especifiquei uma política de estado de funcionamento para a atualização da aplicação, mas a atualização ainda falha em alguns tempos limite que nunca especificei

Quando as políticas de estado de funcionamento não são fornecidas ao pedido de atualização, são retiradas do ApplicationManifest.xml da versão atual da aplicação. Por exemplo, se estiver a atualizar a Aplicação X da versão 1.0 para a versão 2.0, são utilizadas políticas de estado de funcionamento da aplicação especificadas para na versão 1.0. Se uma política de estado de funcionamento diferente deve ser utilizada para a atualização, a política tem de ser especificada como parte da chamada à API de atualização da aplicação. As políticas especificadas como parte da chamada à API só se aplicam durante a atualização. Assim que a atualização estiver concluída, são utilizadas as políticas especificadas no ApplicationManifest.xml .

Foram especificados tempos limite incorretos

Pode ter-se perguntado sobre o que acontece quando os tempos limite são definidos de forma inconsistente. Por exemplo, pode ter um UpgradeTimeout inferior ao UpgradeDomainTimeout. A resposta é que é devolvido um erro. Os erros são devolvidos se UpgradeDomainTimeout for inferior à soma de HealthCheckWaitDuration e HealthCheckRetryTimeout ou se UpgradeDomainTimeout for inferior à soma de HealthCheckWaitDuration e HealthCheckStableDuration.

As minhas atualizações estão a demorar muito tempo

O tempo de conclusão de uma atualização depende das verificações de estado de funcionamento e dos tempos limite especificados. As verificações de estado de funcionamento e os tempos limite dependem do tempo que demora a copiar, implementar e estabilizar a aplicação. Ser demasiado agressivo com tempos limite pode significar mais atualizações falhadas, pelo que recomendamos que comece de forma conservadora com tempos limite mais longos.

Eis uma atualização rápida sobre como os tempos limite interagem com os tempos de atualização:

As atualizações para um domínio de atualização não podem ser concluídas mais rapidamente do que HealthCheckWaitDuration + HealthCheckStableDuration.

A falha na atualização não pode ocorrer mais rapidamente do que HealthCheckWaitDuration + HealthCheckRetryTimeout.

O tempo de atualização de um domínio de atualização é limitado por UpgradeDomainTimeout. Se HealthCheckRetryTimeout e HealthCheckStableDuration não forem zero e o estado de funcionamento da aplicação continuar a mudar para trás e para a frente, a atualização acaba por exceder o limite de tempo em UpgradeDomainTimeout. UpgradeDomainTimeout começa a contar quando a atualização do domínio de atualização atual começar.

Passos seguintes

Atualizar a sua Aplicação Com o Visual Studio orienta-o através de uma atualização da aplicação com o Visual Studio.

Atualizar a sua Aplicação Com o PowerShell orienta-o através de uma atualização da aplicação com o PowerShell.

Controle a forma como a sua aplicação é atualizada através dos Parâmetros de Atualização.

Torne as atualizações da sua aplicação compatíveis ao aprender a utilizar a Serialização de Dados.

Saiba como utilizar funcionalidades avançadas ao atualizar a sua aplicação ao referir-se a Tópicos Avançados.