Arquitetura de Microsserviços

navio-conteiners-microsserviços
Blog Aliado / Blog Aliado / Blog do Diego

Arquitetura de Microsserviços

Monólitos

Quem assistiu ao filme 2001: Uma Odisseia no Espaço, vai se lembrar da primeira cena do filme e que ela, a Odisseia, não tem nada a ver com o espaço. É uma das cenas mais famosas do cinema que mostra um grupo de hominídeos na aurora da evolução humana, tendo que lidar com um estranho objeto que surge do nada. Um monólito retangular e negro que obviamente não se parece em nada com o resto da paisagem. Algo nitidamente artificial em um mundo composto apenas por aquilo que a natureza criou sozinha.

Esta cena termina com um passo importante na evolução daquele grupo, a percepção do uso de ferramentas (no caso um osso), que permite ao símio transformar o mundo a sua volta com mais eficiência do que usando as próprias mãos. Com certeza um avanço tecnológico importante.

Alguns milhares de anos depois, um coletivo de artistas achou que seria engraçado colocar alguns monólitos parecidos com os do filme espalhados em desertos. A ideia era provocar as pessoas para que pensassem que alienígenas teriam feito contato conosco neste ano de 2020 (tornando-o ainda mais maluco).

Disse tudo isso para conseguir fazer a afirmação (em tom de piada):

“Hoje em dia é mais comum aparecer um monólito no deserto do que em um serviço na nuvem”.

O monólito no filme representava o avanço tecnológico, mas em computação hoje, um monólito é na verdade algo ultrapassado. Mas, antes, vamos explicar o que é um monólito (em termos de software).

A abordagem tradicional empregada na construção de aplicações é baseada em construções monolíticas. Isso significa que você constrói uma aplicação que concentra em si todas as partes que podem ser implantadas (em termos de funcionalidades). Ou seja, você tem um “sistemão”. Nele está tudo que ele se propõe a fazer: imagine um software de gestão da companhia com folha de pagamento, faturamento, controle de estoque, financeiro etc. Este software tem milhares (ou talvez milhões) de linhas de código. Um modelo de dados com centenas (ou milhares) de tabelas. O esforço para atender tantas necessidades diferentes é gigantesco. Alguém pode argumentar que grandes aplicativos como estes são divididos em módulos, mas esta divisão não reduz o acoplamento. Emitir uma nota fiscal de venda, por exemplo, gera movimentações de estoque e gera lançamentos na contabilidade e no contas a receber. Mesmo que você diga que são módulos separados, na prática, o programa que gera a nota fiscal interage (de forma muito próxima) com o módulo de estoque, financeiro e contábil (muitas vezes gravando informações diretamente nas tabelas deles).

O principal problema então que um sistema desses cria é, na verdade, fruto do seu próprio sucesso. Explico: quanto mais um sistema ajuda na operação da companhia, mas se investe nele e isto o faz crescer. Em alguns anos o sistema fica gigante. Ele pode até funcionar bem, mas cada nova necessidade leva mais tempo (e, portanto, custa mais) para ser tempo e, o pior, na tentativa de criar melhorias outras partes começam a não funcionar direito. O pesadelo é se alguma mudança no mundo real forçar uma grande alteração no sistema. Neste caso o céu é o limite para o esforço que pode ser exigido na alteração e nos testes.

Brincando de Lego

Ultimamente os problemas relacionados à abordagem de construção monolítica vem assombrando cada vez mais as companhias (lembrem-se sempre que um problema de software não é da TI, é da companhia como um todo). Cada vez mais fica complicado lidar com atualizações de um aplicativo, já que os sistemas acabam abarcando cada vez mais responsabilidades dentro de uma companhia. Se você tem um único aplicativo que faz tudo, então mesmo que você queira apenas mudar a cor de um texto na tela, o aplicativo precisa ser atualizado e isto acaba por impactá-lo em sua totalidade.

Há estratégias como modularização que tentam minimizar este problema, mas ela traz novas complexidades durante a definição da arquitetura do sistema. Além disso, algumas tecnologias te permitem atualizar apenas uma parte do aplicativo (como uma DLL por exemplo), mas te forçam a reiniciar o aplicativo para que a mudança seja efetivada, o que resulta na necessidade de uma janela de atualização que não afete os usuários, pois o sistema ficará invariavelmente indisponível.

Tendo isto em mente, uma alternativa foi pensada. E se não tivéssemos apenas um grande aplicativo, mas usássemos vários aplicativos menores e independentes que pudessem trabalhar juntos? Essa ideia também não é necessariamente nova e traz algumas complexidades de comunicação entre os diversos aplicativos, mas, ela tem uma vantagem, e ela é grande: independência.

Os aplicativos ainda precisam se falar, mas ser independente significa que eles devem estar preparados para que seus parceiros (outros aplicativos) estejam indisponíveis. Também devem estar preparados para que, quando esta indisponibilidade temporária cessar, consigam reestabelecer os serviços à normalidade sozinhos.

Agora cada aplicativo é uma peça de Lego. Ele se liga aos outros, mas também pode existir sozinho. Pode também ser intercambiado.

Cada um no seu quadrado

Legal! Mas, isto pode sair do controle rapidamente. Manter um aplicativo funcionando, às vezes, é desafiador. Manter dezenas ou até centenas deles, funcionando e conversando entre si tem potencial para se tornar um desastre rapidamente. De repente uma atualização de sistema operacional faz metade dos aplicativos pararem de funcionar, ou, se eu precisar aumentar a capacidade dos sistemas como eu faço? Coloco mais servidores? Com todos os aplicativos? Pode demorar semanas para instalar tudo. E uma atualização massiva de vários aplicativos (como uma nova versão)?

Concordo que pode assustar um pouco no começo. O problema na verdade é que enxergamos cada um destes aplicativos como um ser autônomo. Cada um com um nome, uma necessidade, uma tarefa. Elas são tão diferentes entre si, que cada um destes aplicativos pode ter seus próprios problemas e, consequentemente, suas próprias soluções. O que demandaria um exército de técnicos para manter tudo funcionando.

Precisamos simplificar as coisas. Temos de tratar cada aplicativo separado, mas externamente eles devem parecer iguais. Isto diminui muito a complexidade dos times de sustentação. Daí veio a inspiração para um conceito que entendo ser primordial para a adoção com sucesso de uma arquitetura de microsserviços. Containers.

A ideia é enxergar este conjunto de aplicativos como caixas. Como em um grande cargueiro que carrega milhares de containers. Tem contêineres com carros, outros com frutas, outros com componentes eletrônicos. Para o navio não faz tanta diferença do que há lá dentro. Algumas coisas são diferentes, containers refrigerados precisam estar conectados a uma fonte de energia, por exemplo, mas no resto são iguais.

Isto significa que o espaço no navio ocupado por cada um é igual. A fixação deles é igual. O guindaste para carregar e descarregar é igual. O caminhão que transporta é igual.

Se cada microsserviço estiver em um container, então instalar uma nova versão é igual, migrar o serviço para outro servidor é igual, backup é igual, etc. Assim como os containers refrigerados do mundo real, alguns containers de microsserviços precisam de cuidados especiais. Alguns precisam de acesso à internet, outros de acesso à impressora, etc, mas, para o administrador dos sistemas são basicamente iguais.

O que se ganha?

Em suma, com os microsserviços você tem muito mais possibilidades de landscape. Um aplicativo monolítico precisa ser escrito para funcionar em mais de um servidor. Microsserviços fazem isto naturalmente.

Isso permite a você se adaptar muito rapidamente às mudanças. Pode escalar verticalmente e horizontalmente. Em tempos de computação sob demanda, isto é um diferencial competitivo importantíssimo. Um grande varejista pode aumentar sua capacidade computacional em 10 vezes apenas para o Dia das Mães e pagar um adicional pelo hardware para um serviço de nuvem apenas para aquele período.

Já a “conteinerização” é o meio para tornar uma arquitetura de microsserviços melhor gerenciável. Não é a única forma, mas me parece ser a mais eficiente. Cada aplicativo carrega em seu container tudo o que precisa para funcionar de forma autônoma. Este ambiente é o mesmo que o time de desenvolvimento e testes tinha em mãos. Não há mais possibilidade de que algo do ambiente impacte de forma diferente o teste em ambiente de qualidade e o mesmo aplicativo em produção.

Estes dois aliados podem permitir grandes ganhos no controle de custos e na capacidade de adaptação da sua companhia.

 

Gostou desse artigo? Comente!
Artigo escrito por:

diego-yegros-perfil

Diego Yegros (Alliance Consultoria)

Com 22 anos de experiência, atua como Arquiteto de Soluções em empresas multinacionais do segmento de TI, definindo a arquitetura, gerenciamento e implementando inúmeros projetos de alta complexidade para SAP, SAP S4/ HANA.
Participa desde 2005 de inúmeras iniciativas tecnológicas envolvendo SAP e totalmente engajado nos projetos recentes do SAP S/4 HANA, com ênfase no desenho de soluções de aplicativos orientados para área fiscal e contábil. Desde 2013, integra e coopera com as equipes de tecnologia da SAP na solução fiscal TDF.
Sua experiência e conhecimento das mais modernas tecnologias para o desenvolvimento de aplicações, tem sido determinante na definição das estratégias de criação de soluções de software.
Formado em Análise de Sistemas e Direito, com diversos cursos de especialização em sua área de atuação.
Linkedin

Deixe seu comentário aqui!

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *