Partilhar via


Tratamento transitório de falhas (criando aplicativos de nuvem Real-World com o Azure)

por Rick Anderson, Tom Dykstra

Baixar o Projeto de Correção ou Baixar E-book

O livro eletrônico Criando Aplicativos de Nuvem do Mundo Real com o Azure é baseado em uma apresentação desenvolvida por Scott Guthrie. Ele explica 13 padrões e práticas que podem ajudá-lo a desenvolver aplicativos Web para a nuvem com êxito. Para obter informações sobre o livro eletrônico, consulte o primeiro capítulo.

Quando você está projetando um aplicativo de nuvem do mundo real, uma das coisas que você precisa pensar é como lidar com interrupções temporárias de serviço. Esse problema é exclusivamente importante em aplicativos de nuvem porque você é tão dependente de conexões de rede e serviços externos. Muitas vezes, você pode obter pequenas falhas que normalmente são auto-curadas e, se você não estiver preparado para lidar com elas de forma inteligente, elas resultarão em uma experiência ruim para seus clientes.

Causas de falhas transitórias

No ambiente de nuvem, você verá que falha e conexões de banco de dados ocorre periodicamente. Isso ocorre em parte porque você está passando por mais balanceadores de carga em comparação com o ambiente local em que o servidor Web e o servidor de banco de dados têm uma conexão física direta. Além disso, às vezes, quando você depende de um serviço multilocatário, você verá as chamadas para o serviço ficarem mais lentas ou atingirem o tempo limite porque outra pessoa que usa o serviço está atingindo-o fortemente. Em outros casos, você pode ser o usuário que está atingindo o serviço com muita frequência, e o serviço deliberadamente limita você – nega conexões – a fim de impedir que você afete negativamente outros locatários do serviço.

Usar a lógica de repetição/retirada inteligente para atenuar o efeito de falhas transitórias

Em vez de lançar uma exceção e exibir uma página de erro ou não disponível para seu cliente, você pode reconhecer erros que normalmente são transitórios e repetir automaticamente a operação que resultou no erro, na esperança de que em pouco tempo você seja bem-sucedido. Na maioria das vezes, a operação terá êxito na segunda tentativa e você se recuperará do erro sem que o cliente tenha conhecimento de que houve um problema.

Há várias maneiras de implementar a lógica de repetição inteligente.

  • O grupo Práticas de & padrões da Microsoft tem um bloco de aplicativo de tratamento de falhas transitório que faz tudo para você se você estiver usando ADO.NET para acesso Banco de Dados SQL (não por meio do Entity Framework). Basta definir uma política para novas tentativas – quantas vezes tentar novamente uma consulta ou comando e quanto tempo aguardar entre tentativas – e encapsular o código SQL em um bloco de uso .

    public void HandleTransients()
    {
        var connStr = "some database";
        var _policy = RetryPolicy.Create < SqlAzureTransientErrorDetectionStrategy(
            retryCount: 3,
            retryInterval: TimeSpan.FromSeconds(5));
    
        using (var conn = new ReliableSqlConnection(connStr, _policy))
        {
            // Do SQL stuff here.
        }
    }
    

    O TFH também dá suporte ao Cache In-Role do Azure e ao Barramento de Serviço.

  • Quando você usa o Entity Framework, normalmente não está trabalhando diretamente com conexões SQL, portanto, não pode usar esse pacote Padrões e Práticas, mas o Entity Framework 6 cria esse tipo de lógica de repetição diretamente na estrutura. De maneira semelhante, você especifica a estratégia de repetição e, em seguida, o EF usa essa estratégia sempre que acessa o banco de dados.

    Para usar esse recurso no aplicativo Corrigir, basta adicionar uma classe derivada de DbConfiguration e ativar a lógica de repetição.

    // EF follows a Code based Configuration model and will look for a class that
    // derives from DbConfiguration for executing any Connection Resiliency strategies
    public class EFConfiguration : DbConfiguration
    {
        public EFConfiguration()
        {
            AddExecutionStrategy(() => new SqlAzureExecutionStrategy());
        }
    }
    

    Para Banco de Dados SQL exceções que a estrutura identifica como erros normalmente transitórios, o código mostrado instrui o EF a repetir a operação até três vezes, com um atraso exponencial entre repetições e um atraso máximo de 5 segundos. O recuo exponencial significa que, após cada tentativa com falha, ele aguardará um período mais longo antes de tentar novamente. Se três tentativas seguidas falharem, ela gerará uma exceção. A seção a seguir sobre disjuntores explica por que você deseja retirada exponencial e um número limitado de repetições.

    Você pode ter problemas semelhantes ao usar o serviço de Armazenamento do Azure, como o aplicativo Fix It faz para Blobs e a API do cliente de armazenamento do .NET já implementa o mesmo tipo de lógica. Basta especificar a política de repetição ou você nem precisa fazer isso se estiver satisfeito com as configurações padrão.

Disjuntores

Há várias razões pelas quais você não quer repetir muitas vezes por um período muito longo:

  • Muitos usuários que repetem solicitações com falha persistente podem prejudicar a experiência de outros usuários. Se milhões de pessoas estiverem fazendo solicitações repetidas de repetição, você poderá estar amarrando filas de expedição do IIS e impedindo que seu aplicativo atendesse solicitações que, de outra forma, ele poderia lidar com êxito.
  • Se todos estiverem tentando novamente devido a uma falha de serviço, pode haver tantas solicitações enfileiradas que o serviço será inundado quando ele começar a se recuperar.
  • Se o erro for devido à limitação e houver uma janela de tempo que o serviço usa para limitação, as repetições contínuas poderão mover essa janela para fora e fazer com que a limitação continue.
  • Você pode ter um usuário aguardando a renderização de uma página da Web. Fazer as pessoas esperarem muito tempo pode ser mais irritante que relativamente rapidamente aconselhá-las a tentar novamente mais tarde.

O back-off exponencial resolve alguns desses problemas limitando a frequência de repetições que um serviço pode obter do seu aplicativo. Mas você também precisa ter disjuntores: isso significa que, em um determinado limite de repetição, seu aplicativo para de tentar novamente e executa alguma outra ação, como uma das seguintes:

  • Fallback personalizado. Se você não conseguir obter um preço das ações da Reuters, talvez você possa obtê-lo da Bloomberg; ou se você não conseguir obter dados do banco de dados, talvez você possa obtê-los do cache.
  • Falha silenciosa. Se o que você precisa de um serviço não for tudo ou nada para seu aplicativo, basta retornar nulo quando não conseguir obter os dados. Se você estiver exibindo uma tarefa Corrigir e o serviço Blob não estiver respondendo, você poderá exibir os detalhes da tarefa sem a imagem.
  • Falhe rapidamente. Erro do usuário para evitar inundar o serviço com solicitações de repetição que podem causar interrupção de serviço para outros usuários ou estender uma janela de limitação. Você pode exibir uma mensagem amigável "tente novamente mais tarde".

Não há nenhuma política de repetição de tamanho único. Você pode repetir mais vezes e esperar mais tempo em um processo de trabalho em segundo plano assíncrono do que faria em um aplicativo Web síncrono em que um usuário está aguardando uma resposta. Você pode esperar mais tempo entre as tentativas de um serviço de banco de dados relacional do que faria para um serviço de cache. Aqui estão algumas políticas de repetição recomendadas de exemplo para dar uma ideia de como os números podem variar. ("Primeiro Rápido" significa nenhum atraso antes da primeira repetição.

Exemplo de políticas de repetição

Para Banco de Dados SQL diretrizes de política de repetição, consulte Solucionar problemas de falhas transitórias e erros de conexão para Banco de Dados SQL.

Resumo

Uma estratégia de repetição/retirada pode ajudar a tornar os erros temporários invisíveis para o cliente na maior parte do tempo, e a Microsoft fornece estruturas que você pode usar para minimizar seu trabalho implementando uma estratégia se você estiver usando ADO.NET, o Entity Framework ou o serviço de Armazenamento do Azure.

No próximo capítulo, veremos como melhorar o desempenho e a confiabilidade usando o cache distribuído.

Recursos

Para saber mais, consulte os recursos a seguir:

Documentação

Vídeos

Exemplo de código