O blog da AWS
Uma abordagem multidimensional proativa para evitar falhas operacionais, Parte 1: Camada de Aplicação
Por Piyali Kamra, Aish Gopalan, Isael Pimentel, e Aditi Sharma
A resiliência de aplicações supera todos os outros aspectos em relação à confiança de seus clientes. Ao invés de simplesmente reagir a uma falha, por que não sermos proativos?
À medida que um sistema expande, provavelmente encontraremos problemas que podem prejudicar a capacidade de dimensionamento, como segurança e custo. Portanto, é necessário pensar antecipadamente nos padrões de arquitetura corretos, minimizando chances de encontrar falhas que não possuam um plano adequado de recuperação.
Nesta série de blogs em 3 partes, mostraremos como adotar uma abordagem multidimensional para garantir que suas aplicações, infraestrutura e processos operacionais possam detectar pontos de falha, e consigam reagir normalmente se (e inevitavelmente quando) ocorrer uma falha.
Em cada parte da série, recomendamos padrões de arquitetura de resiliência e serviços gerenciados a serem aplicados em todas as camadas de um sistema distribuído, para criar uma aplicação resiliente e pronta para produção. Nessa parte 1, examinamos como criar resiliência na camada de aplicação.
Exemplo de caso de uso
Para ilustrar nossas recomendações sobre como construir um sistema distribuído eficaz, consideraremos um sistema simples de pagamento de compras. A Figura 1 mostra nossa implementação base. A parte de tempo real do sistema distribuído é composta por:
- O serviço de DNS Amazon Route 53, resolve o endereço IP do website e encaminha as requisições para o serviço de distribuição de conteúdo Amazon CloudFront.
- O serviço de distribuição de conteúdo mantém o conteúdo estático do website armazenado no Amazon Simple Storage Service (Amazon S3)em seu cache
- O Application Load Balancerprocessa o conteúdo dinâmico de forma balanceada para os serviços de API do backend
- Amazon ElastiCacheprovê uma camada de cache do banco de dados, para um acesso mais rápido às consultas mais frequentes
- Amazon Aurora, um banco de dados relacional que armazena os dados do sistema
- Finalmente, o Amazon OpenSearch Servicepermite que usuários pesquisem dados utilizando a interface de busca
Para agregar e analisar os dados desse sistema transacional fazemos uso do Amazon Simple Queue Service (Amazon SQS), AWS Lambda, AWS Step Functions, Amazon S3, e Amazon Athena. Usaremos o Amazon Kinesis Data Firehose e Amazon Redshift para popular o nosso armazém de dados através de pipelines de dados. O Amazon QuickSight nos permite visualizar os dados necessários.
Em seguida, vamos analisar os padrões de arquitetura distribuídos que podemos aplicar à esta implementação base para reforçar a resiliência e as desvantagens mais comuns que você precisa considerar para cada um deles.
Padrão 1: Microsserviços
Microsserviços (micro-services) são como blocos de construção, cada um com uma responsabilidade específica. Conforme discutido no whitepaper Micro-services on AWS, estes oferecem muitos benefícios. Além de reduzir o raio de impacto de uma determinada falha, podem ser gerenciados por equipes menores, além de simplificar as etapas necessárias para implantá-los em produção.
Desvantagens e soluções alternativas
Se o seu sistema distribuído for composto por vários serviços menores, a impossibilidade de lidar com uma falha em um serviço pode afetar os outros serviços interconectados.
Para resolver esses problemas, considere implementar um ou mais dos seguintes padrões.
Padrão de Circuit breaker
Como um disjuntor elétrico, o padrão de circuit breaker interrompe as falhas em cascata. Você pode implementá-lo como um orquestrador, em um nível de microsserviço individual e/ou em um conjunto de serviços, para detectar problemas no tempo de execução e rastrear falhas entre serviços, impedindo que o sistema distribuído fique sobrecarregado.
Tentativas com recuo exponencial e jitter
Uma maneira comum de lidar com os problemas de acesso à banco de dados é executando novas tentativas sequenciais. No entanto, se vários processos repetirem tentativas de acesso múltiplas vezes, poderá resultar num congestionamento de acesso de rede ao banco de dados.
Recomendamos a utilização de recuo exponencial (exponential backoff) e jitter quando aplicações enfrentam problemas de acesso ao banco, introduzindo um elemento de aleatoriedade no intervalo entre repetições nas tentativas de acesso.
Para fins de exemplo, considere a implementação de back-end do sistema de pagamento de compras em nosso exemplo, conforme mostrado na Figura 2.
Para quaisquer pedidos recebidos, o processo de pagamento deve ser bem-sucedido para que o pedido seja processado. Para garantir que a latência no acesso ao banco de dados de pagamentos não afete as transações lidas do banco de dados para o processamento de pedidos, devemos:
- Isolar leituras e escritas utilizando conceitos de banco Primário e Réplica.
- Utilizar o Amazon RDS Proxypara lidar com pools de conexão, e assim ajudar a evitar o congestionamento e o bloqueio no acesso ao banco de dados.
- Introduzir recuo exponencial, para aumentar o tempo entre as tentativas subsequentes a falhas de acesso. Combine esta abordagem com jitter para prevenir rajadas de novas tentativas de acesso.
A Figura 3 compara o tempo de recuperação com recuo exponencial e recuo exponencial combinado com jitter:
Verificações de disponibilidade e sinalizadores de recursos
Se você implanta uma nova funcionalidade em produção, e ela não funciona conforme o esperado, use feature toggles para desativá-la em vez de voltar a versão anterior. Isso ajuda a reduzir a complexidade operacional e o tempo de inatividade. Consulte o artigo Automatizando implantações de forma segura e práticas para obter mais informações.
O balanceador de carga utiliza verificações automáticas periódicas de disponibilidade para determinar se o serviço de back-end está funcionando e pode receber tráfego. A Figura 4 mostra onde usar verificações de disponibilidade superficiais e profundas:
- Utilize verificações de disponibilidade superficiais para investigar falhas de host/localizadas em um recurso de servidor (por exemplo, ping e outros testes de disponibilidade).
- As verificações de disponibilidade profundas detectam falhas de dependências. As verificações de disponibilidade profundas fornecerão uma melhor compreensão da disponibilidade do sistema, mas são de complexidade maior e mais cara. Uma falha na verificação de dependência pode causar falhas em cascata em todo o sistema.
Padrão 2: Saga
O padrão saga mantém seus dados consistentes em microsserviços quando uma transação necessita consumir vários serviços. Ele atualiza cada serviço com uma mensagem ou evento ao passar para a próxima etapa da transação.
Por exemplo, em nosso sistema de pagamento de compras, uma transação é considerada bem-sucedida se o pagamento desse pedido for processado corretamente.
Desvantagens e soluções alternativas
O padrão saga é ótimo para transações longas. No entanto, se uma etapa do processo não puder ser concluída, você precisará de transações de correção para desfazer quaisquer alterações das etapas anteriores. Por exemplo, conforme mostrado na Figura 5, se o pagamento falhar, o pedido do cliente deve ser cancelado.
Considere implementar o padrão a seguir para configurar transações de correção.
Padrão Saga Serverless com Step Functions
Recomendamos usar um orquestrador serverless em Step Functions para voltar para uma etapa anterior em um pedido. A Figura 6 mostra o orquestrador serverless e como seu serviço de controle centralizado e simples coordena o fluxo entre os microsserviços. Ele executa transações de correção durante cenários de falha, garantindo que outros microsserviços não falhem, em caso de falha anterior.
Padrão 3: Arquitetura orientada em eventos
Uma arquitetura orientada a eventos utiliza mensagens para se comunicar entre serviços independentes. Ao torná-los independentes, cada serviço se comunica pelo roteador de eventos (também chamado Event Bus), e não diretamente com o outro. Isso significa que os serviços são interoperáveis, mas caso um falhar, o restante continuará funcionando normalmente. O roteador de eventos atua como um buffer elástico que acomoda picos de utilização.
Desvantagens e soluções alternativas
Uma arquitetura orientada a eventos oferece várias opções de implementação. Considere cuidadosamente as especificidades do seu sistema e as necessidades de dimensionamento e desempenho para decidir sobre qual abordagem é a mais adequada.
O mapa mental na Figura 7 mostra nossas recomendações para quando utilizar um padrão orientado a eventos, opções de correções e soluções alternativas:
Padrão 4: Uso de Cache
A implantação de instâncias redundantes que não precisem manter controle de sessão, juntamente com o uso de caches distribuídos, pode melhorar a disponibilidade de suas aplicações. Ele permite que sua infraestrutura seja redimensionada em resposta ao volume de usuários.
Desvantagens e soluções alternativas
Os caches possuem várias opções de configuração. Considere cuidadosamente as especificidades do seu sistema e as necessidades de dimensionamento e desempenho para decidir qual abordagem é mais adequada.
O mapa mental na Figura 8 mostra nossas recomendações para utilização de cada tipo de cache, opções de correções e soluções alternativas:
Melhorando a resiliência de aplicações limitando seus contextos
Uma vez que os serviços sejam independentes um dos outros, sua disponibilidade aumenta mais do que expandir horizontalmente a capacidade dos mesmos. A Figura 9 mostra os benefícios de um sistema com independência entre serviços versus um sistema tradicional acoplado.
Conclusão
Neste post, aprendemos sobre vários padrões de arquitetura e suas desvantagens, fornecendo recomendações sobre como mitigar falhas antes que elas aconteçam.
Os sistemas distribuídos podem utilizar todos esses padrões, o que ajuda a melhorar a resiliência na camada de aplicação. A utilização desses padrões, juntamente com as melhorias de infraestrutura e operações discutidas nas partes 2 e 3, fornecerá estruturas mais resilientes para suas aplicações.
Este artigo foi traduzido do Blog da AWS em Inglês.
Sobre os autores
Piyali Kamra é uma experiente arquiteta empresarial e tecnóloga com mais de 21 anos de experiência prática na criação e execução de projetos de TI corporativos de grande escala internacional. Ela acredita que construir sistemas corporativos de grande escala não é uma ciência exata, mas sim uma arte, onde nem sempre é possível escolher a melhor tecnologia que vem à mente, mas ferramentas e tecnologias devem ser cuidadosamente selecionadas com base na cultura, pontos fortes, fracos e riscos do time, além de ter uma visão futurista de como você deve moldar produtos que resistam à prova do tempo.
Aish Gopalan é uma Arquiteta de Soluções Sênior na AWS baseado na bela cidade de Atlanta, Geórgia. Como colaboradora individual, ela ocupou vários cargos, desde Arquiteta de Soluções, Arquiteta de Aplicativos, Líder de Entrega de Transformação em Nuvem e Desenvolvedora em sua jornada de software de mais de 16 anos. Sempre animada, ela pratica Crossfit e acredita em viver o momento.
Isael Pimentel é um Gerente Técnico de Contas sênior na AWS com mais de 15 anos de experiência no desenvolvimento e gerenciamento de infraestruturas complexas e possui várias certificações, incluindo AWS Solution Architect, AWS Network Specialty, AWS Security Speciality, MSCA e CCNA.
Aditi Sharma é uma Gerente Técnica de Contas na AWS e iniciou sua jornada como engenheira de suporte de nuvem na equipe de bancos de dados RDS. Desde então, ela ocupou várias funções na AWS antes de passar para a função atual. Antes de ingressar na AWS, ela trabalhava como engenheira de desenvolvimento de software no setor bancário. Aditi possui mestrado em Sistemas de Informação Gerencial e Bacharelado em Engenharia de Ciência da Computação e também Certified Scrum Master, Product Owner e AWS Associate Solutions Architect.
Tradutor
Renato Fichmann é um Arquiteto de Soluções Sênior na AWS, com mais de 20 anos de experência em TI, sendo a maior parte dela em funções relacionadas com serviços gerenciados de TI (ITSM), com foco nos processos de resiliência, governança, e disponibilidade de sistemas. Além das certificações ITIL e TOGAF, Renato é certificado AWS Professional Solutions Architect.