Uma das práticas mais recomendadas para equipes dedicadas ao desenvolvimento de produtos digitais que desejam alcançar 99,999% de disponibilidade é rastrear versões de aplicativos e serviços e aprofundar o conhecimento no que se diz respeito às dependências entre eles. Essa prática faz parte do velho e bom – embora frequentemente ignorado – Gerenciamento de Configuração.
Uma Matriz de Resiliência é uma ferramenta que exibe os aplicativos e serviços de um determinado produto e conecta todos os aplicativos às suas dependências. Mas não para por aí: é possível também visualizar o nível de impacto causado a um aplicativo a partir de falhas causadas em cada uma das dependências. Com isso, é possível identificar e corrigir o que efetivamente está causando um problema para um cliente com muito mais rapidez.
O desafio do monitoramento na nuvem
Em um passado não muito distante, geralmente as empresas tinham em seus ambientes locais (on-premise) um número limitado de recursos de infraestrutura, e com arquiteturas estáticas. Após configurar o monitoramento para esses aplicativos, a ideia é que eles não exigiriam atualizações com frequência.
Mas, ao avançarmos para o momento presente, muitos aplicativos nativos da nuvem foram construídos em 2020 enquanto aplicativos tradicionais acabaram reformulados para se beneficiarem da nuvem. Pois bem: agora que as arquiteturas se tornaram elásticas e distribuídas, o monitoramento tornou-se um enorme desafio para rastrear alvos móveis. Alguns aplicativos são executados em implementações do tipo IaaS, ou Infraestrutura como Serviço; outros já são executados como componentes PaaS (de uma Plataforma como Serviço) e um número crescente de aplicativos é adquirido como ofertas SaaS, de software como serviço.
Como podemos lidar com isso?
Existe uma frase famosa no mundo Cloud/DevOps: “Trate os servidores como gado, não como animais de estimação”.
A imagem abaixo ilustra bem isso:
Afinal, ninguém pode guiar o gado chamando cada vaca pelo nome. Seria uma tarefa humanamente impossível.
Na verdade, se você precisa cuidar de vários animais de estimação de uma vez, poderá conhecer e interagir com cada um deles sem maiores problemas, certo? Isso é o que os administradores de sistema eram capazes de fazer com seus servidores durante a era pré-nuvem.
No entanto, se você precisa gerenciar centenas de componentes que mantêm seu produto em funcionamento – da mesma forma que uma pessoa guiando o gado, como no exemplo acima – será necessário aprender novas técnicas, tais como monitoramento e rastreamento distribuído. A boa notícia é que, com apenas algumas configurações e convenções, será possível manter centenas ou mesmo milhares de componentes menores.
Como as transações agora acontecem em vários locais, o processo de monitoramento deve ser capaz de rastrear e agregar cada etapa. O gerenciamento de log também mudou muito, já que muitas máquinas e containers possuem pequenos ciclos de vida. O processo de log padrão agora envolve log centralizado com pilhas como ELK ou Graylog, entre outras.
A combinação dessas novas ferramentas e processos é frequentemente chamada de “Observability” (“Observabilidade”), pois representa muito mais do que um simples monitoramento. Falaremos muito sobre o assunto neste blog.
Produtos, aplicativos e serviços
Mas antes mesmo de avançarmos no tema do monitoramento, é fundamental alinharmos a semântica e explicar como definimos cada um dos elementos que compõem sua estrutura.
Produto é algo que uma empresa oferece a seus clientes ou talvez a um grupo interno de funcionários. Ele tem um significado comercial e geralmente é composto por vários aplicativos e serviços.
Aplicativo é algo que a empresa desenvolve internamente (talvez com a ajuda de parceiros ou contratados) para criar valor dentro de um contexto de Produto. Normalmente melhora com o tempo e contempla atualizações frequentes através correções de bugs e implementação de novos recursos. Aplicativos geralmente dependem dos Serviços para funcionar.
Serviço é algo que a empresa usa para construir Aplicativos. Pode ser um serviço de infraestrutura como um banco de dados ou algo mais sofisticado, como uma API de Preços.
Embora servidores, containers e outros componentes técnicos passem por alterações com alta frequência em ambientes de nuvem, por outro lado, os produtos, aplicativos e serviços sofrem muito menos alterações. Eles também são muito mais relevantes para os clientes, por isso faz sentido monitorá-los ao invés de peças móveis subjacentes.
As melhores práticas ITIL recomendam o uso de um Configuration Management Database (CMDB) para gerenciar servidores e outros tipos de dispositivos, que geralmente estão vinculados a ambientes legados on-premise. A maior parte das ideias por trás dessas práticas ainda são relevantes em ambientes de nuvem quando há uma mudança de mentalidade.
Afinal, é possível gerenciar, como ambientes, Aplicativos, Serviços e outras entidades relevantes, em um Catálogo de Aplicativos e Serviços. E gerenciar o ciclo de vida do aplicativo torna-se muito mais fácil com informações de qualidade disponíveis no Catálogo.
Verificações de Integridade
Quando o foco são componentes de alto nível, como Aplicativos, é preciso haver rotinas eficazes para verificar se tudo está funcionando como deveria. Aqui podemos fazer uma analogia com um avião, onde evidentemente desejamos ter a certeza de que tudo esteja em funcionamento nas mais perfeitas condições, filtrando todo e qualquer ruído ao redor.
Isso é feito através de verificações de integridade do aplicativo (conhecidas como “health-checks”). Muito resumidamente, executar um health-check é uma forma de verificar se um aplicativo está rodando bem e sem problemas. Os aplicativos devem ser construídos tendo o conceito de Observability em mente, o que torna mais fácil descobrir se algo precisa ser feito ou não.
Vamos a um exemplo prático. Quando uma verificação de integridade é executada, um aplicativo deve comunicar-se com cada um de seus serviços da mesma forma que faz o tempo todo; se precisar de dados de um banco de dados, ele deve buscar obter dados desse banco de dados. Se precisar enviar e-mail para clientes, deve tentar enviar um e-mail simples para um endereço real. Desta forma, se enfrentarmos qualquer tipo de problema, o health-check nos informará imediatamente em qual verificação houve a falha.
Exemplo de uma Matriz de Resiliência: One Platform
Abaixo temos uma amostra de como funciona uma Matriz de Resiliência, extraída da nossa plataforma de monitoramento One Platform:
Neste exemplo, temos 4 aplicativos, em colunas:
Admin
Provisionador
1P-Backend
Steras
Em cada linha da Matriz, podemos ver as dependências de Aplicativo e de Serviço. Vamos escolher o aplicativo 1P-Backend para descrever suas dependências:
1P-Nats-prod: serviço de infraestrutura
1P-Elasticsearch-prod: serviço de infraestrutura
Sendgrid: serviço externo
1P-Postgres-prod: serviço de infraestrutura
1P-Redis-prod: serviço de infraestrutura
Uma coisa interessante sobre a Matriz é que ela facilita a verificação sobre o que pode estar causando um problema específico no sistema. Dessa forma, quando ocorre um incidente, podemos verificar instantaneamente se alguma dependência também está falhando, e com isso agilizar a resolução de problemas, tudo em tempo real e em questão de segundos.
Em cada célula da Matriz de Resiliência temos 1 de 3 opções, a depender do impacto que uma dependência causa nos aplicativos a ela associados:
Disponível: quando o aplicativo tolera falhas na dependência sem nenhum impacto relevante para seus clientes
Degradado: quando o aplicativo ainda pode operar parcialmente, mas não possui parte de seu comportamento usual. Exemplo: quando o Youtube para de renderizar miniaturas, mas continua reproduzindo vídeos
Indisponível: quando o aplicativo não pode servir ao seu propósito
Existem algumas técnicas que os aplicativos podem usar durante as falhas, como o do padrão Circuit Breaker. No entanto, como projetar um sistema para lidar com falhas e construir aplicativos resilientes são temas para outros artigos que abordaremos neste blog futuramente. Então assine a nossa newsletter e fique ligado! 🙂
E como otimizar as verificações de integridade?
Ao conhecer as dependências, é possível aprimorar as verificações de integridade para validá-las adequadamente. Como cada serviço é monitorado de forma independente, no health-check da OnePlatform é possível validar que cada aplicativo use com sucesso a dependência correspondente.
Um exemplo seria fazer uma consulta no banco de dados ou tentar escrever e ler de um serviço em cache. Ao fazer isso, é possível ter a certeza de que as credenciais e a rede também estão funcionando sem problemas.
Ao tomarmos novamente como exemplo o aplicativo 1P-Backend, um payload de verificação de integridade se pareceria com o que segue:
{
"1P-Nats-prod" : "OK",
"1P-Elasticsearch-prod": "OK",
"Sendgrid" : "ERROR",
"1P-Postgres-prod" : "OK",
"1P-Redis-prod" : "OK"
}
Temos vários atributos de valor-chave, um para cada dependência, e valores simples como “OK” e “ERROR” para descrever se o aplicativo é capaz de usar a dependência ou não. Neste exemplo, a única dependência com falha é a Sendgrid.
Isso não quer dizer que Sendgrid está desativado para todos; pode ser apenas um problema com a conta. O que é relevante aqui é o fato de que os emails transacionais provavelmente não estão sendo enviados, uma vez que a dependência que cuida disso está retornando erros para o aplicativo.
Essa abordagem para verificação de integridade é recomendada a todos os aplicativos, devido à sua simplicidade e aos ganhos que traz para o diagnóstico e para a resolução de problemas.
A Matriz de Resiliência em uma organização
Embora seja relativamente fácil compreender uma Matriz com vários aplicativos e serviços, é uma tarefa que pode se tornar muito mais complexa quando temos dezenas ou mesmo centenas de apps e serviços em uma mesma matriz.
No entanto, as equipes de produto normalmente não gerenciam tantos aplicativos e serviços. Normalmente, para um determinado Produto, você precisará apenas de uma ou 2 matrizes para exibi-lo por completo. Já em uma organização, você pode ter muitas matrizes se tiver muitas equipes de produto, mas cada matriz estará focada em um domínio específico.
Se você deseja aplicar as técnicas descritas neste post com sua equipe, sinta-se à vontade para entrar em contato conosco!