Como preparar sua arquitetura para trabalhar com microserviços

A noite de quinta-feira, 18 de maio, foi bem animada na Superlógica Tecnologias. O palco foi montado para uma noite de meetup com 2 tech-talks da Rivendel, um do CEO Bruno Pereira – que descreveremos detalhadamente neste post – e outro do Caio Teixeira, sobre Tsuru, que detalharemos na próxima postagem. Bruno falou tanto sobre um conjunto de abordagens e preocupações que as empresas têm quando estão portando uma aplicação antiga para um modelo de microserviços como o que deve ser considerado quando iniciamos uma aplicação nova com esse modelo, que benefícios e outras coisas importantes a considerar.

Baby steps

O primeiro contato de Bruno Pereira com o ecossistema de microserviços aconteceu quando integrou a equipe de tecnologia do Globo.com, em 2007, onde trabalhava bastante com cadastro de usuários, autenticação, autorização e APIs de várias aplicações do portal, como o Cartola. “Lá foi a primeira oportunidade que eu tive de trabalhar com algo parecido com microserviços”, conta Bruno. “A gente tinha algumas aplicações em Java na época, já tínhamos alguma segmentação de aplicações em banco de dados, foi o meu primeiro contato com REST também”. Na visão dele, trabalhar com microserviço converge quase sempre para usar APIs mais flexíveis, sem a necessidade de manter-se ‘amarrado’ a uma estrutura de base de dados que depois não poderá ser mexida. “Por essa razão o REST é um componente super próximo com microserviços. Temos trabalhado vários anos com times de operações que buscam arquiteturas escaláveis e no final das contas o que a gente quer é que seja uma operação bem tolerante a falhas, bem resiliente e que consiga escalar horizontalmente”.

Bruno conta que criou a Rivendel há 4 anos com esse propósito, e que trabalha de forma bem próxima principalmente com a Amazon e a Microsoft, além do Google Cloud, Openstack e Cloudstack. “Hoje em dia o que a gente vê são várias empresas usando modelos híbridos, muitas vezes você não encontra uma única nuvem e o fato de trabalhar com microserviços ajuda nisso, a caminhar para um modelo mais de container, é possível então portar o ambiente muito mais facilmente, você pode ter um data center on-premise, um data center com nuvem pública, ou cooperando ao mesmo tempo”, explica.

Para ele, poder dimensionar o impacto físico de um volume mais previsível e poder transportar para a nuvem pública só por um período curto, com pico de acesso é “o sonho de quem trabalha com infraestrutura” e, nesse sentido, trabalhar com microserviço e com container ajuda bastante porque há uma portabilidade; ele ressalta que há vários benefícios em focar em uma plataforma de nuvem x, “mas há necessidade de ficar preso a uma específica se houver incentivo para usar outra”.

“Na Rivendel trabalhamos com startups que criam aplicações novas o tempo inteiro e já buscam um modelo mais fluído de serviço. E também trabalhamos com inovação e modelo mais ‘digital enterprise’, que são aplicações muitas vezes integradas com modelos mais antigos”.

“A gente hoje suporta algum modelo de maturidade de microserviços, estamos com mais de 1 mil em produção hoje, e sabemos bem como são as nuances nos times de desenvolvimento, e vamos dar algumas dicas de como fazer isso da forma mais alinhada com as melhores práticas”, disse, no início da palestra.

Afinal, o que são microserviços?


micro-service-architecture

Bruno conceitua microserviços como sendo um estilo de arquitetura que usa componentes menores e com baixo acoplamento entre eles. “Essa questão do baixo acoplamento de como você consegue de fato ter um contato de comunicação mais leve permite uma curva de evolução tecnológica mais fácil de manter”, explica.

“Se você tem uma API REST que contata um JSON, se tem implementado em Ruby ou Java e quer trocar para Python ou qualquer outra coisa, contanto que você tenha uma API de contato você consegue trocar, e com isso consegue ter múltiplos times trabalhando em linguagens e frameworks diferentes numa mesma empresa. Isso é o que a gente vê hoje porque se pegamos uma empresa com 50, 100 desenvolvedores, é muito difícil ter 100 desenvolvedores bons trabalhando na mesma linguagem hoje, todo mundo com a mesma visão de tecnologia, então é muito comum ter outras aplicações e outras equipes trabalhando cada uma com uma linguagem”.

Normalmente o microserviço implementa uma pequena função de negócio, como microserviço que cuida de autenticação e autorização, microserviço que cuida de checkout, enfim, microserviço para qualquer corte de modelagem de negócio que o usuário venha a ter. São composições de aplicações com ‘quebras’ de blocos maiores em múltiplas aplicações, normalmente com múltiplos serviços que chamamos via http para renderizar uma tela e fazer várias queries.

Isso muda um pouco a abordagem e normalmente quando temos esse desacoplamento tecnológico também conseguimos ter múltiplas linguagens e frameworks trabalhando juntos e isso é algo que traz mais flexibilidade para a empresa. Hoje em dia a cada dois anos aproximadamente muda a estrutura das tecnologias; por exemplo, quem começou trabalhando com Java, agora trabalha com Ruby ou Node. É uma opção tecnológica que traz mais flexibilidade e governança para a empresa ao longo do tempo.

Um time de desenvolvimento está criando uma única aplicação monolítica, que é o que compõe aquele produto sendo desenvolvido. Isso acaba convergindo em crescimento para múltiplos times trabalhando naquele monolito – Bruno conta que, quando trabalhou para o projeto do Hotel Urbano, tinha uma única aplicação com múltiplos deploys com até 10 times trabalhando em paralelo em uma única aplicação e mesmo repositório, o que também rapidamente converge para uma dificuldade maior em ter uma base de código saudável, o que também acaba trazendo uma complexidade razoável ao projeto.

Então já devo começar minha aplicação com microserviços?



Faz sentido pensar em iniciar uma aplicação com microserviços como algo obrigatório? Bruno cita o autor Steve Blank ao mencionar que “startups são organizações temporárias projetadas para encontrar um modelo de negócios repetível e escalável”. Ou seja, enquanto você não encontra esse modelo de negócios e tenha algo que de fato deu certo já e saiba que vai se tornar uma empresa ou produto que será mantido a longo prazo, praticamente tudo é descartável, então enquanto você não tem um modelo validado, que sabe que vai ter demanda, aquilo serve de aprendizado, mas não é algo a se apegar. “Uma premissa interessante de negócios sob o ponto de vista da inovação é a de que quando estamos lançando um produto novo e não sabemos se terá aceitação, qualquer coisa que for feita ali será para validar se o cliente de fato está comprando, por exemplo, e então é possível ter uma visão de que o produto chegou em um nível de sucesso/maturidade com gente suficiente usando”. Em caso negativo, o que foi feito é descartado.


Então ao compararmos um time de desenvolvimento trabalhando em um modelo monolítico, com um modelo de microserviços com certeza é bem mais rápido iterar em outra escala em uma única aplicação ao invés de criar um modelo mais distribuído. Criar um modelo mais distribuído significa que você terá múltiplas APIs, múltiplos deploys e múltiplos componentes que podem falhar. “Se você tem um produto e não sabe ainda qual a composição definitiva dele, portanto é algo que você pode descartar e jogar fora, é mais rápido iterar isso em ciclos curtos de prototipação em uma única aplicação – por exemplo, com uma pessoa mexendo no front-end – com tudo integrado, do que com microserviços”. Microserviço faz sentido normalmente quando você já sabe o que precisa ser construído, e aí constrói de forma eficiente e em escala.

Preparando sua aplicação para microserviços



Com o quê exatamente o DevOps deve se preocupar ao criar uma aplicação bem sucedida em termos de engenharia e operação? Normalmente, os objetivos gerais são construir arquiteturas escaláveis horizontalmente. “Isso é muito importante. Por exemplo, em uma visão de cluster, é possível obter um custo basal pequeno e aumentar a quantidade de máquinas em paralelo quando houver um pico. No caso da Black Friday, por exemplo, ao invés de 2 máquinas em horário comercial é possível ter 200 operando, em um pico absurdo, e isso pode acontecer tanto em datas especiais para o varejo como para aplicações mais específicas que requerem maior poder de processamento no horário comercial”, explica Bruno.

“Nesse contexto, quando há uma estrutura de escalabilidade horizontal é possível aumentar ou diminuir a quantidade de componentes horizontalmente e isso traz um custo de operação muito mais baixo, o custo da Amazon ou da plataforma de nuvem vai ser bem menor”. Bruno acrescenta que também é possível obter maior tolerância a falhas quando se escala horizontalmente. Então, por exemplo, se você tiver um componente falhou em um pull de 10 servidores, é só tirá-lo do pull e seguir atendendo os usuários de forma satisfatória. Muitas das falhas que vão acontecendo com a infraestrutura – e as falhas acontecem o tempo inteiro – elas acabam não gerando grande impacto ao usuário final, o que também é bem importante hoje em dia.

Desafios comuns


“É preciso trabalhar os servidores como gado, não como bicho de estimação. Existem múltiplos componentes que podem surgir e serem destruídos várias vezes ao dia, por isso é preciso levar em conta uma abordagem focada em automação, o que implica em um controle de estado de um jeito diferente de como era antigamente” comenta Bruno. “Por exemplo: não adianta ter uma sessão http dentro de uma máquina local. Isso não vai funcionar bem se você tem máquinas entrando ou saindo do cluster. É preciso ter componentes capazes de aumentar linearmente a escrita”. Ou seja, ao trabalhar de uma forma onde seja possível crescer horizontalmente e que não implique em um componente pesado corporativo que custa caro, isso confere à organização maior estabilidade e uma capacidade de crescimento muito mais atraente.

Uma alta disponibilidade geográfica também é super desejável, com mais de um data center rodando em paralelo, para proteção extra: em caso de emergência, é possível chavear para o data center que estiver funcionando.

12 Factor App”



Como poderia ser um modelo para pensar o desenvolvimento e assegurar uma boa resiliência? Bruno cita o “12 Factor App, um conjunto de 12 recomendações que oferecem diretrizes de boas práticas que fornecem vários insights interessantes para uma operação mais eficiente:

1. Base de Código – Base de código em repositórios independentes para cada microserviço e com pipelines independentes;

2. Dependências – Declare e isole as dependências; crie uma matriz de resiliência

3. Configurações – Gerência de configuração fácil de automatizar e manter

4. Serviços de apoio – Tratar os serviços de apoio também como microserviços e dependências desacopladas

5. Build, Release, Run – Pipelines com etapas distintas e bem granulares

6. Processos – Execute a aplicação como um ou mais processos que não armazenam estado

7. Vínculo de porta – Exporte serviços fazendo bindings nas portas (usar sempre DNS para permitir indireção e a melhor resolução)

8. Concorrência – Dimensione por um modelo de processo; testes de carga validam capacidade do processo e o quanto a arquitetura cresce linearmente aumentando as unidades

9. Descartabilidade – Maximizar a robustez com inicialização e desligamento rápido (containers)

10. Desenvolvimento e produção semelhantes – Mantenha os ambientes o mais próximo possíve

11. Logs – Trate logs como fluxo de eventos; centralizadores de logs permitem escalabilidade horizontal e melhor visibilidade

12. Processos Admin – Ferramentas de administração separadas em processos pontuais

Quer saber como chegar lá? Assista ao vídeo com a íntegra da palestra de Bruno Pereira:

21