Alura > Cursos de Back-end > Cursos de Arquitetura de Software > Conteúdos de Arquitetura de Software > Primeiras aulas do curso Cloud Native: arquitetura, multicloud e FinOps

Cloud Native: arquitetura, multicloud e FinOps

Arquiteturas cloud native e multicloud - Migração lift and shift

Apresentando o curso e o instrutor

Olá! Boas-vindas ao curso Arquiteturas Cloud Native (Nativa em Nuvem) e Multicloud (Multinuvem). Ao longo deste curso, veremos um caso de uso que ilustra como podemos — ou não — nos beneficiar das plataformas em nuvem, considerando a criação e a migração de aplicações do ambiente on-premises (ambiente local) para a nuvem.

Meu nome é Daniel Amaral.

Audiodescrição: Daniel é um homem de pele morena, com cabelo e barba pretos; usa óculos de armação preta e uma camiseta vinho.

Contextualizando o negócio e estratégias de migração

Vamos começar pelo primeiro módulo, no qual entenderemos o contexto do negócio, algo essencial quando falamos de arquitetura de soluções. Inicialmente, nós nos concentraremos no desafio de uma empresa que deseja migrar uma aplicação existente, que hoje está em um centro de dados privado, para uma nuvem pública, e entenderemos os desafios envolvidos nesse tipo de iniciativa.

Nesse processo, existem várias formas de conduzir a migração. Uma delas é o que chamamos de lift and shift (elevar e migrar), que consiste em levar o que está no centro de dados para a nuvem pública tal como está, utilizando recursos computacionais muito semelhantes aos usados localmente. Abordaremos os prós e contras dessa estratégia, além de como podemos evoluir a adoção de nuvem de forma mais estratégica.

Apresentando o caso de uso e conceitos cloud native

A empresa que servirá como pano de fundo do nosso caso de uso é a Amaral Seguros, uma seguradora que possui hoje uma plataforma de e-commerce (comércio eletrônico) em funcionamento, executando em ambiente on-premises (ambiente local), no próprio centro de dados. A equipe de arquitetura deseja se beneficiar do uso de recursos em nuvem, especialmente pela escalabilidade e pela agilidade no provisionamento de infraestrutura. Vamos entender os desafios e o que ocorreu durante essa migração.

Um ponto muito importante quando falamos de Cloud Native (Nativa em Nuvem) é que esse conceito se refere a como projetamos a solução e não necessariamente ao local onde a executamos. Executar na nuvem não implica, por si só, benefícios. Dependendo de como a aplicação está arquitetada, o custo de infraestrutura em nuvem pode aumentar a ponto de inviabilizar o uso desses recursos. Surge então o debate: a nuvem é cara ou barata? É melhor manter máquinas próprias? Tudo depende de como a aplicação é arquitetada. Não existe uma única forma de operar uma aplicação em um ambiente de nuvem pública. Há diversas possibilidades: diferentes recursos, várias maneiras de executar uma aplicação monolítica, e diferentes abordagens para aplicações projetadas em microserviços e orientadas a eventos. Portanto, a forma como projetamos a aplicação influencia diretamente o quanto nos beneficiamos do uso de recursos de nuvem pública.

Detalhando a arquitetura atual e a migração lift and shift

A arquitetura atual da plataforma de e-commerce (comércio eletrônico) da Amaral Seguros é uma aplicação monolítica desenvolvida em Java, com um banco de dados MySQL. Essa aplicação integra-se com outro sistema interno criado em .NET, que, por sua vez, se comunica com uma aplicação externa de gateway de pagamentos, responsável por intermediar a comunicação com operadoras de cartão de crédito, entre outras formas de pagamento. Em uma visão macro, essa é a aplicação de e-commerce em si.

O que a equipe de arquitetura da Amaral Seguros fez? Em um primeiro momento, escolheu o provedor de nuvem Google Cloud e moveu os módulos da aplicação para máquinas virtuais (VMs). No Google Cloud, essas VMs são chamadas de Compute Engine; na AWS, um serviço equivalente seria o EC2, por exemplo. O monólito da aplicação foi migrado para uma instância de Compute Engine; o banco de dados MySQL foi movido para outra instância de Compute Engine; e o sistema interno em .NET foi empacotado e implantado também em uma instância de Compute Engine. Com isso, tudo passou a executar na nuvem. Foi um caminho simples, seguindo a estratégia de lift and shift (elevar e migrar).

Esclarecendo limites da abordagem e consequências iniciais

Nós mantivemos a aplicação exatamente como estava no ambiente on-premises (instalação local) e a levamos para a cloud (nuvem) usando o recurso mais próximo do que existia no ambiente on-premises (instalação local): máquinas virtuais (VMs). É uma opção válida e pode ser um caminho inicial. No entanto, isso não significa que a aplicação tenha se tornado cloud native (nativa em nuvem) simplesmente por utilizarmos um recurso na cloud (nuvem).

Vejamos o que ocorreu no caso da Amaral Seguros com essa migração e a estratégia adotada. Recapitulando o que foi feito: foi preparada uma série de servidores e a migração foi realizada. Não houve nenhuma refatoração de código nem de arquitetura. Qual é a armadilha dessa estratégia? Havia problemas de escalabilidade e disponibilidade; a aplicação caía quando atingia picos de consumo. Isso não melhorou. A equipe apenas passou a contar com uma forma mais simples de provisionar máquinas virtuais. Como resultado, a aplicação está na cloud (nuvem), mas não é cloud native (nativa em nuvem) e não se beneficia das melhores práticas nem dos recursos disponíveis. É provável, inclusive, que essa aplicação tenha um custo elevado.

Relatando os impactos de picos de tráfego e dimensionamento

Logo após a migração, foi lançada uma grande campanha de marketing (divulgação) para promover os produtos e serviços da seguradora. Houve contratação de futebolistas e inserções em comerciais durante a telenovela. O resultado foi caótico: o site caiu, ocorreram picos de acesso e as VMs não suportaram; a aplicação ficou indisponível. As equipes precisaram migrar para máquinas maiores, com mais recursos computacionais, mais memória e mais CPU. Contudo, pela forma como a aplicação estava configurada, era necessário realizar uma série de configurações na máquina antes de implantar a solução, o que demandou um processo demorado para restabelecer a aplicação.

No fim do mês, a fatura chegou rapidamente — e estava muito alta. Com receio de novas quedas, a equipe escolheu máquinas dimensionadas para atender ao pico de demanda. Imagine um cenário em que o fluxo de usuários sobe e desce: 1.000, 800, 10.000, 2.000. Foi feito o sizing (dimensionamento) considerando o pico. Porém, como o pico ocorre apenas eventualmente, para evitar indisponibilidade, a aplicação acabou sendo mantida em uma infraestrutura muito robusta para atender qualquer pico de consumo que surgisse. Funciona? Funciona. O problema é o custo. Manter uma infraestrutura preparada para o maior pico de consumo quando, na maior parte do tempo, esse não é o comportamento habitual do tráfego, desequilibra o custo em relação ao fluxo de consumo. Isso resultou em uma fatura muito alta no fim do mês.

Avaliando os resultados e lições sobre maturidade em nuvem

Houve perda de receita, clientes migraram para a concorrência e a campanha de marketing (divulgação) não gerou o ROI (retorno sobre investimento) esperado devido aos custos de infraestrutura. Foi uma migração para a cloud (nuvem) que produziu um efeito inverso: em vez de garantir disponibilidade, manteve os mesmos problemas e ainda gerou questões de custo e reputação.

Esse cenário ilustra o que ocorre em muitas empresas que estão iniciando sua jornada na cloud (nuvem). Nós já trabalhamos em organizações onde começamos a usar a cloud (nuvem) e esse tipo de situação, de fato, aconteceu. Naquele momento, ainda não havia maturidade: conhecíamos bem a aplicação e o negócio, mas ainda não conhecíamos bem a cloud (nuvem) e seus caminhos. A cloud (nuvem) não é apenas VM; a VM é apenas um componente muito básico. Ao compararmos on-premises (instalação local) e cloud (nuvem), existem muitos outros elementos que podem atuar como aceleradores e nos ajudar a projetar uma arquitetura que, considerando componentes de infraestrutura, alcance a escalabilidade e a disponibilidade necessárias para as soluções atuais.

Encaminhando os próximos passos e encerramento

Nos próximos vídeos, vamos desenvolver e entender como poderíamos fazer isso de outra forma e qual estratégia a Amaral Seguros poderia ter adotado.

Agradecemos a atenção. Até a próxima.

Arquiteturas cloud native e multicloud - Princípios do 12-Factor App

Contextualizando a migração e avaliando o lift and shift

Perfeito, pessoal. Dando continuidade, nós vimos que a migração que a Amaral Seguros fez para a nuvem da plataforma de comércio eletrônico não saiu bem. Os problemas foram mantidos e ainda surgiram outros, relacionados a custos e despesas de infraestrutura em nuvem.

Um ponto importante: isso não significa que o lift and shift (migração direta) nunca deva ser utilizado. Nós já trabalhamos em cenários em que a infraestrutura que o cliente tinha em on-premises (ambiente local) havia atingido um limite e, para provisionar mais servidores, era necessário comprá-los, entregá-los no data center (centro de dados) e passar por um processo que levava semanas ou até meses. Assim, a simples velocidade de provisionar infraestrutura — por exemplo, quando temos um servidor com capacidade X e precisamos do dobro ou do triplo — já pode ser um benefício.

O ponto central é: executar uma aplicação na nuvem não a torna, por si só, cloud native (nativa em nuvem). O lift and shift pode ser interessante e gerar valor para a empresa em alguns casos, mas isso não transforma a aplicação em uma aplicação cloud native (nativa em nuvem).

Introduzindo a transformação para cloud native

A questão, então, é como transformar uma aplicação para adotar boas práticas e ser, de fato, cloud native (nativa em nuvem). Existem caminhos, boas práticas e estratégias que podemos adotar.

Um conjunto muito relevante é o da 12-Factor App (aplicativo de 12 fatores), que consolida boas práticas. Foi criado pela Heroku, empresa que oferece uma plataforma em nuvem para provisionamento de recursos computacionais, bancos de dados, servidores, entre outros. O time da Heroku, a partir de ampla experiência operacional, listou o que considera as 12 principais estratégias para que uma aplicação se beneficie de ser cloud native (nativa em nuvem). Isso é extremamente relevante, principalmente para estratégias e desenhos de arquitetura baseados em microserviços, embora não seja exclusivo a esse tipo de arquitetura.

Outro ponto importante: nem toda aplicação precisa adotar, necessariamente, os 12 fatores.

Para termos uma visão geral dos 12 fatores, sem aprofundar em cada um deles — há outros cursos na Alura que exploram esse conteúdo em profundidade — destacamos os seguintes princípios e implicações práticas:

Apresentando princípios iniciais dos 12 fatores

Detalhando práticas de estado, servidor e escalabilidade

Precisamos persistir arquivos e registros em um recurso externo — em uma base de dados, em um bucket no Cloud Storage ou em um bucket no S3 —, isto é, fora da infraestrutura computacional onde a aplicação está em execução.

A aplicação não deve depender de implantação em nenhum tipo de servidor externo. Ela deve incluir um servidor embutido. Por exemplo, quando trabalhamos com Spring Boot e geramos o fat.jar, ele inclui automaticamente um Tomcat ou um Jetty para inicializar a aplicação. Assim, o servidor web já vem embutido junto com o fat.jar.

Em concorrência, o ideal é que a aplicação esteja preparada para escalar horizontalmente. Escalar horizontalmente é atender a um fluxo maior de solicitações de pessoas usuárias por meio de cópias, isto é, instâncias paralelas da infraestrutura. Não foi o que aconteceu com a estratégia adotada por Amaral Seguros: fizeram um lift and shift (migração sem refatoração), migrando a aplicação para um Compute Engine, uma VM no Google Cloud, e a aplicação atingiu o limite de recursos. Em seguida, precisaram migrá-la para outro servidor, para um número maior de servidores, com mais recursos. Isso é o que chamamos de escalabilidade vertical: escalar aumentando a quantidade de recursos computacionais do servidor. Esse processo pode consumir bastante tempo.

A ideia é trabalhar de forma horizontal. Criamos mais instâncias para atender a um fluxo maior e reduzimos o número de instâncias conforme a necessidade. Isso ajuda a obter um custo mais atrativo e uma escalabilidade mais elástica. Podemos criar e eliminar instâncias. Preparar a aplicação para trabalhar de forma horizontal e atender picos de demanda é essencial.

A aplicação deve estar preparada para ser desligada e ligada sem problemas. Se precisarmos eliminar uma instância que está executando a aplicação, ela deve ser capaz de tomar os dados que estão em cache, persistir em algum lugar e realizar verificações para que a interrupção não gere inconsistências de dados. Isso é o que chamamos de graceful shutdown (desligamento ordenado).

Garantindo paridade e observabilidade entre ambientes

Paridade entre ambientes: precisamos garantir que os ambientes de desenvolvimento, homologação e produção sejam equivalentes. Não necessariamente em recursos computacionais, mas em estruturas e tecnologias utilizadas. Quando trabalhamos com Docker, isso se simplifica bastante. Independentemente de estarmos executando a aplicação no notebook pessoal, em um servidor local (on-premises) ou no servidor de produção, na nuvem A, B ou C, a aplicação está sendo executada em um contêiner autocontido. Esse é o ecossistema que o software percebe. Onde o recurso computacional de fato está, onde o contêiner roda, é indiferente para a aplicação. A paridade torna-se muito mais simples quando trabalhamos com aplicações conteinerizadas.

O item 11 trata de logs. Nossa aplicação deve ser projetada para simplesmente gerar um stream (fluxo) de logs continuamente. Outra ferramenta ficará responsável pela ingestão, tratamento e suporte à observabilidade da aplicação, sem adicionar complexidade à aplicação principal. A aplicação apenas precisa gerar os logs — por dia, por hora ou em um arquivo único —, e uma ferramenta externa processará esses logs, gerará métricas, apoiará a monitoração e permitirá a adoção inteligente de uma estratégia de observabilidade.

Tratando processos administrativos e planejando a adoção por etapas

Por fim, processos administrativos pontuais devem ser tratáveis de forma replicável. Por exemplo, ao criarmos uma nova versão da aplicação que implica criar ou alterar tabelas, incluir colunas ou renomear uma tabela, ao replicar isso para um ambiente de desenvolvimento ou produção, não deve ser necessário que uma pessoa desenvolvedora acesse o ambiente A, B ou C para executar scripts manualmente. Isso é suscetível a erro e não é boa prática. A boa prática é ter um script que simplesmente precise ser executado: um script é criado e executado em desenvolvimento, homologação e produção para replicar as mudanças. Usamos base de dados como exemplo, mas poderia ser qualquer outro tipo de configuração. Isso não deve fazer parte da aplicação; não devemos criar um endpoint apenas para executar esse tipo de tarefa. Em vez disso, devemos ter um processo pontual que se executa, faz o que precisa ser feito e não será executado novamente.

Essa é a visão geral dos 12 fatores. Reforçando: não é esperado que todas as aplicações adotem necessariamente todas essas estratégias. Adotaremos muitas delas quando já tivermos pavimentado o caminho de como nossa empresa trabalha, com uma arquitetura de referência definida, e não precisaremos nos preocupar com isso para cada aplicação. Em alguns casos, teremos aplicações que precisarão escalar verticalmente, pois dependem de mais recursos computacionais. Ainda assim, esse panorama indica o que precisamos adotar para alcançar o cenário de uma aplicação Cloud Native (nativa em nuvem).

Por último, não precisamos adotar tudo de uma vez; podemos avançar em ondas, incorporando essas boas práticas quando partimos de um cenário em que nada disso está em execução.

Perfeito, pessoal. Até o próximo vídeo. [♪]

Arquiteturas cloud native e multicloud - Estratégias Cloud Native

Apresentando a visão macro dos 12 factors

Visão macro dos 12 Factors

Cobrimos, em nível macro, o que são os 12 Factors. Para aprofundar a visão dos 12 Factors, podemos acessar 12factor.net/pt_br. Ao clicar, por exemplo, no primeiro tópico (Base de código), há uma descrição detalhada sobre a recomendação de manter uma base de código única, uma única fonte, considerada para múltiplos ambientes. Apresentamos essa referência para mostrar a origem dos conceitos.

Iniciando a aplicação na Amaral Seguros

Aplicação na Amaral Seguros

Para a aplicação da Amaral Seguros, vamos considerar inicialmente três fatores:

Podemos melhorar esta aplicação aplicando os 12 Factors? Precisamos adotar todos, necessariamente, para modernizá-la? Não. Fazer tudo de uma vez pode inviabilizar o negócio. O time to market (tempo de lançamento no mercado) é muito importante. Ao pensarmos em arquitetura e soluções, precisamos sempre ponderar a perspectiva técnica aliada à perspectiva de negócio.

No caso do e-commerce de uma seguradora, o raciocínio também se aplica a um portal de uma empresa de varejo que esteja se preparando para a Black Friday. Não podemos re-arquitetar toda a aplicação e perder a oportunidade de ter um bom desempenho na Black Friday. Precisamos considerar a estratégia de negócio, o momento em que o negócio se encontra e o que está sendo planejado ao desenhar a arquitetura. Às vezes, podemos ter como meta o ótimo, mas algo bom já gera grande valor para o negócio, como garantir melhor disponibilidade.

Com a aplicação desses fatores, já conseguiremos garantir escalabilidade horizontal e melhor disponibilidade para o e-commerce da Amaral Seguros. Estamos falando de um monolito. Ao aplicar alguns fatores, teremos uma solução que se beneficia desses princípios; não será o cenário ótimo, mas já poderemos categorizá-la como uma solução Cloud Native (nativo em nuvem).

Relacionando cloud native e boas práticas do setor

Cloud Native e CNCF

Os 12 Factors apresentam boas práticas que ajudam a orientar nossa aplicação como um serviço Cloud Native. A CNCF (Cloud Native Computing Foundation) publica um manifesto com boas práticas e definições sobre o que é Cloud Native. Em visão macro, destacamos:

Do nosso ponto de vista, podemos desfrutar dos benefícios de uma solução Cloud Native sem necessariamente adotar microserviços. Microserviços não são uma bala de prata e não devem ser perseguidos em qualquer solução. Em alguns casos, podemos adotar uma estratégia monolítica.

Destacando pontos de infraestrutura e observabilidade

Outros pontos importantes:

Falamos sobre malhas de microsserviços com comunicação segura entre serviços, com monitoramento e escalabilidade, que, principalmente, abstraem da pessoa que está desenvolvendo os recursos computacionais toda a complexidade de redes. E, de forma extremamente importante, observabilidade. Precisamos garantir que a aplicação seja observável. Após realizar o deploy (implantação), precisamos monitorar para assegurar visibilidade, resiliência adequada e promover melhoria contínua. Se conseguimos observar a aplicação — volume de erros, métricas, recursos computacionais consumidos — podemos trabalhar em estratégias de melhoria contínua a partir desses dados. Certo?

Projetando para falhas e definindo disponibilidade

Outro ponto extremamente relevante, quando falamos de soluções em nuvem de forma geral, é projetar para a falha. O que significa isso? De fato, preocupar-nos com a possibilidade de a aplicação ficar indisponível. Se essa aplicação cair, se a zona onde estamos fazendo o deploy (implantação), isto é, a zona do provedor de nuvem onde estamos implantando, ficar indisponível, o que acontece com a aplicação? Ela cai ou migra automaticamente para outra zona de disponibilidade? Precisamos definir uma estratégia de fallback (contingência). Se cair em uma zona, ela deve subir em outra instância? Precisamos considerar isso como um fato.

Além disso, precisamos desenhar a estratégia de disponibilidade de acordo com a criticidade do negócio e com a criticidade do sistema envolvido. Podemos ter níveis de criticidade diferentes e, consequentemente, requisitos de disponibilidade distintos conforme a aplicação. Uma certeza é que servidores falharão e algum recurso computacional ficará indisponível. Portanto, precisamos projetar a aplicação para garantir alta disponibilidade conforme a demanda do negócio. Não é necessário distribuir globalmente uma aplicação que não é crítica para o negócio; precisamos avaliar a criticidade e desenhar a estratégia de disponibilidade de acordo com isso. Certo?

Comparando métricas mtbf e mttr

Há métricas importantes utilizadas no mercado. MTBF, ou Mean Time Between Failures (Tempo Médio Entre Falhas), que é o tempo entre falhas da aplicação. Quanto maior esse tempo, melhor, pois indica que a aplicação falha pouco. Porém, essa métrica se concentra apenas em evitar a falha a todo custo. Podemos querer criar um sistema que nunca caia. Talvez isso nos leve a montar uma infraestrutura extremamente robusta. Foi, por exemplo, a estratégia que a Amaral Seguros adotou: colocaram um servidor com recursos suficientes para atender a um pico de solicitações. A aplicação não deveria cair por falta de recursos computacionais; entretanto, o custo era elevado, pois o recurso desse servidor era muito mais caro. Isso pode não ser suficiente ou sustentável.

Temos, então, outra métrica, a MTTR, Mean Time To Recover (Tempo Médio de Recuperação), que mede quanto tempo levamos para colocar a aplicação de volta em funcionamento após uma queda. A ideia é que seja o mínimo possível — quanto menor, melhor. Se desenhamos uma estratégia de alta disponibilidade, com escalabilidade horizontal, isso se torna muito mais fácil, além de outras ações possíveis, como manter réplicas entre regiões e entre zonas de disponibilidade para garantir alta disponibilidade. Em alguns cenários, podemos até reduzir a zero o tempo de indisponibilidade, pois, quando a aplicação cai, a queda ocorre apenas em uma das instâncias, desde que tenhamos réplicas implantadas em várias zonas ou regiões — ou até mesmo em diferentes nuvens, em uma estratégia multi-cloud (multinuvem).

Adotando estratégias multicloud e encerrando

Nessa estratégia, mantemos instâncias da aplicação executando na Google Cloud, na Azure e na AWS, e utilizamos um load balancer (balanceador de carga) que distribui as solicitações ou aciona o provedor B quando o A fica indisponível. São caminhos possíveis, cada um com impactos em custo e desempenho. O negócio deve liderar e ser o embaixador do tipo de estratégia que vamos adotar. De acordo?

Perfeito. No próximo vídeo, continuamos com alguns tópicos adicionais e veremos como poderíamos ter adotado essas estratégias na arquitetura da Amaral Seguros. Até o próximo vídeo.

Sobre o curso Cloud Native: arquitetura, multicloud e FinOps

O curso Cloud Native: arquitetura, multicloud e FinOps possui 191 minutos de vídeos, em um total de 47 atividades. Gostou? Conheça nossos outros cursos de Arquitetura de Software em Back-end, ou leia nossos artigos de Back-end.

Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:

Aprenda Arquitetura de Software acessando integralmente esse e outros cursos, comece hoje!

Conheça os Planos para Empresas