Olá, pessoal! Tudo bem?
Hoje vamos finalizar o segundo pilar do Well-Architected Framework, o Reliability Pillar, falando sobre gestão de mundanças e gestão de falhas. A primeira parte deste assunto pode ser acessada aqui.
Design para alta disponibilidade
Geralmente quando uma aplicação é projetada, é muito comum planejarmos uma disponibilidade de “5 noves”, ou seja, 99,999%. Isso quer dizer que, em um ano, o sistema deverá ter menos de 5 minutos de downtime. Felizmente, existe uma série de boas práticas para atingirmos este nível de disponibilidade. Abaixo seguem algumas das principais:
- Redundância de componentes: Uma estratégia para reduzirmos problemas de disponibilidade, é evitarmos pontos únicos de falha. Se possuirmos apenas um recurso oferecendo determinado serviço e ocorrer algum tipo de falha, seja hardware ou software, este serviço ficará indisponível;
- Zonas de isolamento de falhas: A AWS oferece múltiplas zonas de disponibilidade, que são datacenters totalmente isolados, dentro de uma região específica. Devemos utilizar estas zonas para “espalhar” os recursos redundantes para evitar que, caso ocorra algum problema em determinada zona, os serviços oferecidos por estes recursos permaneçam disponíveis;
- Microservices architecture: Arquitetura em microserviços permite que times isolem funcionalidades específicas em pequenos serviços, possibilitando flexibilidade tecnológica, velocidade no deploy, desacoplamento e tolerância a particionamento do sistema, ou seja, se ocorrer uma falha catastrófica em um microserviço, o restante do sistema permanecerá disponível;
- Recovery-Oriented Computing: ROC é um método desenvolvido pela universidade de Stanford para construir arquiteturas resilientes. Além da redundância e isolamento citados nos itens anteriores, ele descreve outras características como: possibilidade de desfazer modificações (undo), possibilidade de monitorar e determinar a saúde do workload, possibilidade de prover diagnósticos automaticamente, recuperação automática, design modular e possibilidade de reiniciar recursos;
- Melhores práticas para sistemas distribuídos: Por termos citado zonas de isolamento e arquitetura em microserviços, estamos também falando de sistemas distribuídos. Portanto, devemos utilizar algumas práticas e padrões para este tipo de sistemas, que melhoram a resiliência de nosso workload. São eles: o padrão Circuit Breaker, o padrão Retry, throttling, idempotency tokens, trabalho constante, falhar rapidamente e comportamento bi-modal.
Para tornar estas tarefas menos onerosas, uma recomendação da AWS é que utilizemos seus serviços gerenciados (como o DynamoDB ou o SQS), ao invés de provisionarmos e mantermos serviços similares, pois existe a garantia de que os serviços da AWS são altamente disponíveis por definição.
Gestão de Mudanças
Mudanças em produção, seja infraestrutura ou novas releases, sempre são perigosas, pois toda mudança pode causar um impacto negativo em nosso Workload, comprometendo sua estabilidade. Por este motivo, devemos monitorar estas mudanças e auditá-las, para sabermos quem fez e quando à mesma foi efetuada, permitindo que ações corretivas sejam feitas de forma rápida, caso necessário.
Quando falamos em publicação de atualizações, devemos utilizar pipelines de CI/CD automatizados, reduzindo assim a possibilidade de existirem erros humanos, e mantendo a consistência das atualizações. Para a etapa de deploy do nosso pipeline, devemos considerar deployment patterns já consolidados para reduzir o risco de downtime em produção, garantindo a disponibilidade do nosso workload. Abaixo seguem os principais patterns:
- Canary deployment: Este tipo de deployment redireciona uma pequena amostragem dos usuários da aplicação para uma nova versão. Esta nova versão é monitorada através de métricas e logs para identificar se a mesma está performando conforme o esperado. Caso algo grave seja detectado, é possível revertê-la, voltando estes usuários à versão anterior;
- Blue/Green deployment: O Blue/Green deployment consiste em fazer o deploy de um segundo ambiente em paralelo com o ambiente de produção. Quando a versão atual em produção for o ambiente Green, a nova versão será publicada no ambiente Blue, e vice-versa. O ambiente de produção será alternado entre Green e Blue (um com a versão corrente e o outro com a nova versão), permitindo que a atualização seja desfeita, caso algum problema seja detectado;
- Feature toggles: Feature toggles permitem a liberação de funcionalidades em um estado inativo, ou seja, o usuário não perceberá alterações no comportamento da aplicação, mesmo após a release. É possível, mediante configuração, ativar esta feature para uma quantidade especifica de usuários, e desativar em caso ela apresente defeito;
- Failure isolation zones deployment: Está estratégia de deployment é utilizada e recomendada pela AWS, e consiste em fazer o deploy sem comprometer duas availability zones de uma vez, para evitar problemas de disponibilidade.
Para alterações na demanda, podemos ajustar a capacidade do nosso workload utilizando autoscaling, permitindo que ajustemos a infraestrutura de forma adequada e automática à estas alterações.
Os serviços da AWS abaixo nos auxiliam na execução destas tarefas:
- Aws CloudTrail: Com o CloudTrail, podemos auditar ações efetuadas em nossa conta na AWS, sabendo quando e por quem foram feitas, com a possibilidade de automatizarmos notificações e respostas a estas mudanças.;
- Aws Config: O AWS Config nos fornece um inventário dos recursos existentes em nossa conta, auxiliando na identificação de atualizações em suas configurações e a responder de forma proativa;
- Amazon CloudWatch: O Amazon CloudWatch permite analisarmos métricas, e criar alarmes e alertas sobre elas;
- AWS Auto Scaling: O AWS Auto Scaling gerencia automaticamente alterações na demanda do workload, garantindo o desempenho do mesmo.
Gestão de Falhas
Falhas sempre acontecerão, por mais que estejamos na defensiva e trabalhemos para evitá-las. Como não podemos evitá-las definitivamente, devemos estar cientes de sua existência o mais rápido possível, utilizando monitoramento de métricas e logs, e remediando estes problemas utilizando automação sempre que possível.
Devemos também analisar recursos que sofreram algum tipo de falha em produção, substituindo o mesmo por outro recurso saudável, e isolando o problemático. Isto é importante para entendermos a causa da falha e efetuar os devidos ajustes, evitando possíveis problemas futuros.
Outro aspecto chave de um sistema resiliente, é a existência de um plano de backup e recuperação de desastres. Devemos ter uma política de backup constante, e automatizar a recuperação de desastres. É importante também efetuarmos testes regularmente e avaliando métricas, como RTO e RPO, para verificar como a estratégia está performando.
Alguns serviços da AWS que podemos utilizar nestes cenários:
- AWS CloudFormation: Permite que o provisionamento de recursos na AWS de forma previsível, permitindo testes e reprodução de falhas;
- Amazon S3 e Amazon Glacier: O S3 e o Glacier são serviços de armazenamento extremamente duráveis, que possibilitam o armazendo de logs e backups;
- AWS KMS: Permite a gestão de chaves de criptografia de forma fácil, além de integrar com diversos serviços da AWS.
Fim
Resiliência e confiabilidade são aspectos chave na aceitação de um sistema por seus usuários. A AWS oferece todos os artefatos necessários para construirmos arquiteturas com estas características, além de prover serviços gerenciados altamente disponíveis, que reduzem consideravelmente dores de cabeça, quando falamos em provisionamento e manutenção.
Era isso, pessoal. Espero que tenham gostado!
Abraços e boa semana!
Um comentário sobre “Well-Architected Framework – Reliability Pillar – Parte 2”