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

Este artigo aborda alguns dos problemas comuns relacionados à atualização de um aplicativo do Azure Service Fabric e como resolvê-los.

Solucionar problemas de uma atualização de aplicativo com falha

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

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

Essas informações estão disponíveis quando o Service Fabric deteta a falha, independentemente de o FailureAction 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 uma falha de atualização foi detetada pelo Service Fabric e FailureAction foi disparada. FailureReason identifica uma das três possíveis causas de alto nível da falha:

  1. UpgradeDomainTimeout - Indica que um domínio de atualização específico demorou muito tempo para ser concluído e UpgradeDomainTimeout expirou.
  2. OverallUpgradeTimeout - Indica que a atualização geral demorou muito para ser concluída e UpgradeTimeout expirou.
  3. HealthCheck - Indica que, após a atualização de um domínio de atualização, o aplicativo permaneceu não íntegro de acordo com as políticas de integridade especificadas e HealthCheckRetryTimeout expirou.

Essas entradas só aparecem na saída quando a atualização falha e começa a ser revertida. Mais informações são exibidas dependendo do tipo de falha.

Investigar tempos limite de atualização

As falhas de tempo limite de atualização são mais comumente causadas por problemas de disponibilidade do serviço. A saída a seguir a este parágrafo é típica de atualizações em que as réplicas ou instâncias de serviço não são iniciadas na nova versão do 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 presas. As partições ficaram presas porque o tempo de execução não pôde colocar réplicas primárias (WaitForPrimaryPlacement) nos nós de destino Node1 e Node4.

O comando Get-ServiceFabricNode pode ser usado para verificar se esses dois nós estão no domínio de atualização MYUD1. O UpgradePhase diz PostUpgradeSafetyCheck, o que significa que essas verificações de segurança estão ocorrendo depois que todos os nós no domínio de atualização terminaram a atualização. Todas essas informações apontam para um possível problema com a nova versão do código do aplicativo. 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 ele ser executado. Os problemas mais comuns neste caso são erros de serviço no fechamento ou rebaixamento de caminhos de código primários.

O UpgradeState atual é RollingBackCompleted, portanto, a atualização original deve ter sido executada com uma reversão FailureAction, que reverteu automaticamente a atualização em caso de falha. Se a atualização original foi executada com um FailureAction manual, a atualização estaria em um estado suspenso para permitir a depuração ao vivo do aplicativo.

Em casos raros, o campo UpgradeDomainProgressAtFailure pode estar vazio se a atualização geral expirar assim que o sistema concluir todo o trabalho para o domínio de atualização atual. Se isso acontecer, tente aumentar os valores dos parâmetros de atualização UpgradeTimeout e UpgradeDomainTimeout e tente novamente a atualização.

Investigar falhas na verificação de integridade

As falhas de verificação de integridade podem ser desencadeadas por vários problemas que podem acontecer depois que todos os nós em um domínio de atualização concluem a atualização e passam por todas as verificações de segurança. A saída após este parágrafo é típica de uma falha de atualização devido a verificações de integridade com falha. O campo UnhealthyEvaluations captura um instantâneo das verificações de integridade que falharam no momento da atualização de acordo com a diretiva de integridade 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              :

A investigação de falhas de verificação de integridade requer primeiro uma compreensão do modelo de integridade do Service Fabric. Mas, mesmo sem um entendimento tão aprofundado, podemos ver que dois serviços não são íntegros: fabric:/DemoApp/Svc3 e fabric:/DemoApp/Svc2, juntamente com os relatórios de integridade de erro ("InjectedFault" neste caso). Neste exemplo, dois em cada quatro serviços não estão íntegros, o que está abaixo da meta padrão de 0% não íntegro (MaxPercentUnhealthyServices).

A atualização foi suspensa após falhar, especificando um FailureAction do manual ao iniciar a atualização. Este modo nos permite investigar o sistema ao vivo no estado de falha antes de tomar qualquer outra ação.

Recuperar de uma atualização suspensa

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

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

O comando Start-ServiceFabricApplicationRollback pode ser usado a qualquer momento para iniciar a reversão do aplicativo. Uma vez que o comando retorna com êxito, a solicitação de reversão foi registrada no sistema e inicia logo em seguida.

O comando Resume-ServiceFabricApplicationUpgrade pode ser usado para prosseguir manualmente pelo restante da atualização, um domínio de atualização de cada vez. Neste modo, apenas as verificações de segurança são realizadas pelo sistema. Não são realizadas mais verificações de saúde. Este comando só pode ser usado quando o UpgradeState mostra RollingForwardPending, o que significa que o domínio de atualização atual terminou a atualização, mas o próximo não foi iniciado (pendente).

O comando Update-ServiceFabricApplicationUpgrade pode ser usado para retomar a atualização monitorada com verificações de segurança e integridade sendo executadas.

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 usa os mesmos parâmetros de atualização e políticas de integridade que antes. Se necessário, qualquer um dos parâmetros de atualização e políticas de integridade mostrados na saída anterior pode ser alterado no mesmo comando quando a atualização for retomada. Neste exemplo, a atualização foi retomada no modo Monitorado, com os parâmetros e as políticas de integridade inalterados.

Resolver mais problemas

O Service Fabric não está seguindo as diretivas de integridade especificadas

Possível causa 1:

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

Possível causa 2:

As políticas de integridade são especificadas em termos de porcentagens do total de serviços e não de instâncias de serviço específicas. Por exemplo, antes de uma atualização, se um aplicativo tiver quatro instâncias de serviço A, B, C e D, onde o serviço D não está íntegro, mas com pouco impacto para o aplicativo. Queremos ignorar o serviço não íntegro conhecido D durante a atualização e definir o parâmetro MaxPercentUnhealthyServices como 25%, supondo que apenas A, B e C precisam estar íntegros.

No entanto, durante a atualização, D pode tornar-se saudável, enquanto C torna-se insalubre. A atualização ainda seria bem-sucedida porque apenas 25% dos serviços não são saudáveis. No entanto, pode resultar em erros imprevistos devido a C ser inesperadamente insalubre em vez de D. Nessa situação, D deve ser modelado como um tipo de serviço diferente de A, B e C. Como as políticas de integridade são especificadas por tipo de serviço, diferentes limites percentuais não íntegros podem ser aplicados a diferentes serviços.

Não especifiquei uma política de integridade para a atualização do aplicativo, mas a atualização ainda falha por alguns tempos limite que nunca especifiquei

Quando as políticas de integridade não são fornecidas para a solicitação de atualização, elas são retiradas do ApplicationManifest.xml da versão atual do aplicativo. Por exemplo, se você estiver atualizando o Aplicativo X da versão 1.0 para a versão 2.0, as políticas de integridade do aplicativo especificadas na versão 1.0 serão usadas. Se uma política de integridade diferente deve ser usada para a atualização, a política precisa ser especificada como parte da chamada de API de atualização do aplicativo. As políticas especificadas como parte da chamada de API só se aplicam durante a atualização. Quando a atualização estiver concluída, as políticas especificadas no ApplicationManifest.xml serão usadas.

Tempos limite incorretos são especificados

Você deve ter se perguntado sobre o que acontece quando os tempos limite são definidos de forma inconsistente. Por exemplo, você pode ter um UpgradeTimeout menor que o UpgradeDomainTimeout. A resposta é que um erro é retornado. Os erros são retornados se UpgradeDomainTimeout for menor que a soma de HealthCheckWaitDuration e HealthCheckRetryTimeout, ou se UpgradeDomainTimeout for menor que a soma de HealthCheckWaitDuration e HealthCheckStableDuration.

Minhas atualizações estão demorando muito

O tempo para a conclusão de uma atualização depende das verificações de integridade e dos tempos limite especificados. As verificações de integridade e os tempos limite dependem do tempo necessário para copiar, implantar e estabilizar o aplicativo. Ser muito agressivo com tempos limite pode significar mais atualizações falhadas, por isso recomendamos começar de forma conservadora com tempos limite mais longos.

Aqui está 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 de atualização não pode ocorrer mais rápido do que HealthCheckWaitDuration + HealthCheckRetryTimeout.

O tempo de atualização para um domínio de atualização é limitado por UpgradeDomainTimeout. Se HealthCheckRetryTimeout e HealthCheckStableDuration forem diferentes de zero e a integridade do aplicativo continuar alternando para frente e para trás, a atualização eventualmente expirará em UpgradeDomainTimeout. UpgradeDomainTimeout começa a contagem regressiva assim que a atualização para o domínio de atualização atual começa.

Próximos passos

Atualizando seu aplicativo usando o Visual Studio orienta você através de uma atualização de aplicativo usando o Visual Studio.

Atualizando seu aplicativo usando o PowerShell orienta você por uma atualização de aplicativo usando o PowerShell.

Controle como seu aplicativo é atualizado usando os Parâmetros de Atualização.

Torne as atualizações do seu aplicativo compatíveis aprendendo a usar a Serialização de Dados.

Saiba como usar a funcionalidade avançada ao atualizar seu aplicativo consultando Tópicos Avançados.