DevSecOps

2 mai, 2018

Dificuldades no uso de Microservices

Publicidade

Já comentamos aqui no portal sobre o que é Microservices, uma abordagem na qual pequenos projetos têm apenas uma responsabilidade. Além disso, cada serviço é autônomo, apesar de trabalhar em conjunto.

Mas como definir o que é pequeno o suficiente?

Jhon Evens (RealEstate.com.au) caracteriza um Microservice como algo que pode ser reescrito em duas semanas. Para Sam Newman, o senso comum é que, uma vez que já não se sinta que um pedaço de código é grande, provavelmente ele já é/está pequeno o suficiente. Eric Evans também cita Context Map para nos ajudar a definir essa responsabilidade.

Afinal, se a abordagem de Microservices é tão boa, por que não foi feito antes?

Uma das respostas é que avanços tecnológicos recentes levaram nossa capacidade técnica a outro nível. Com a crescente popularidade de containers e “tecnologia de orquestração”, por exemplo, toda nova abordagem é mais viável do ponto de vista técnico.

Outro ponto importante é que um dos principais benefícios do uso, de acordo com o que tem sido divulgado, é a fácil escalabilidade e separação de responsabilidades (princípio da responsabilidade única). Entretanto, poucas empresas precisam da escalabilidade que a Netflix ou Spotify precisam, por exemplo. Então por que você deveria usar Microservices?

Os benefícios dos Microservices são muitos e têm sido bastante divulgados. No entanto, nós precisamos entender que existem novos pontos/tipos de falha com os quais essa abordagem tem que lidar. Comunicação via redes pode e vai falhar, serviços e servidores falham ou tornam-se lentos, por exemplo. Precisamos saber como contornar e qual é o impacto que pode existir sobre o usuário final do nosso software.

De fato é uma abordagem muito útil, mas até os seus defensores dizem que o uso deve ser pensado para sistemas mais complexos, pois o uso traz um custo de gestão de serviços extra.

Faça monolítico primeiro

Todos esses argumentos nos levam a pensar melhor na estratégia de usar monolíticos primeiro. A ideia é que você comece por construir uma aplicação monolítica, mesmo que mais tarde ela possa se beneficiar da abordagem de Microservices. Um dos motivos é o clássico Yagni (You Aren’t Gonna Need It – em engenharia de software, uma orientação de trabalho que sugere aos programadores que não adicionem funcionalidades ao código fonte de um programa até que elas sejam realmente necessárias). Além disso, através da identificação do domínio que emergiu no desenvolvimento do monolítico, é possível visualizar melhor a forma com que vamos fazer os splits dos contextos dos microservices.

Limites de contexto

Uma segunda questão é que, começando com Microservices, eles só vão funcionar se você encontrar limites de contexto bons e estáveis entre os serviços, para que quando houver necessidade de alterações, elas não influenciem outros serviços. Qualquer refatoração de funcionalidade entre microservices é muito mais difícil do que em um monolítico.

É importante citar que um Microservice deve ser uma entidade separada, deployada como um serviço isolado. Precisa ser capaz de mudar independentemente de outros serviços, sem requerer mudanças naqueles que o consomem. É preciso avaliar o que deve ser exposto e o que deve ser escondido dos consumidores. Se há muita coisa compartilhada, há diminuição na sua autonomia, o que exige uma coordenação maior para fazer alterações.

Se em um serviço A, onde cada alteração que você fizer nele você precisar alterar algo nos serviços que o consomem, isso significa que há alto acoplamento entre eles e por consequência, baixa autonomia para fazer mudanças, uma vez que isso implica mudar em vários serviços ao mesmo tempo para que uma mudança seja efetiva.

Se você começa a desenvolver seu software de forma modularizada e com os limites bem definidos entres os módulos, mais fácil será a migração de monolítico para Microservice. O design evolutivo reconhece as dificuldades de obter limites de contexto corretos e, portanto, a importância de ser fácil de refatorá-los. Mas quando seus componentes são serviços com comunicações remotas, a refatoração pode ser muito mais difícil do que em serviços únicos, ou seja, monolíticos.

Habilidades

Novas tecnologias geralmente são testadas por equipes mais habilidosas, e sabemos que, mesmo nos monolíticos, muitas vezes a equipe tem dificuldades para lidar com o deploy das aplicações. O que podemos esperar de equipes com menor habilidade no uso da abordagem de Microservices, visto que as ferramentas utilizadas para gerenciar os serviços são relativamente novas e requerem certa expertise para lidar com elas?

Não digo que é impossível que uma equipe “crua” possa adquirir esse novo conhecimento, mas é preciso saber que há uma curva de aprendizado alta que pode demandar um certo tempo até que este time, antes com pouca habilidade, esteja seguro de colocar tudo em produção usando seus novos conhecimentos.

Logs

Em uma arquitetura na qual os serviços são distribuídos e há uma gama muito maior deles, trabalhar com logs pode ser um problema. Chegar ao ponto focal pode demandar uma busca entre diversos Microservices, o que exige maior esforço de gerenciamento para rastrear uma falha.

Rastrear o log de uma aplicação com cinco microservices pode sem bem fácil, mas pense em fazer isso quando você tem mais do que 50 microservices e seus respectivos logs. Já fica bem mais complexo.

Custos

Algumas das coisas que a abordagem de Microservices prega, é a facilidade da integração contínua (CI) e entrega contínua (CD), resiliência e escalabilidade. Para que isso possa existir, é necessário que haja uma automatização dos processos de configuração, ou seja, o uso de scripts de código e ferramentas que levantem e monitorem esses serviços.

Fazer CI/CD para microservices implica maior complexidade do ambiente e preocupação com maior número de pontos de falha. Com isso, pode ser que os custos sejam maiores do que o uso de monolítico. Além disso, ainda há o custo que a equipe pode ter para adquirir know-how de como fazer funcionar e manter esse gerenciamento, pois demanda mais conhecimento de redes e ambientes distribuídos.

Versionamento

A estratégia de versionamento dos serviços deve estar muito bem elaborada. Uma vez que haja o crescimento do ambiente com mais Microservices e necessidade de mais alterações importantes, pode ser bem complicado gerenciar as versões de cada serviço de forma que os consumidores sejam pouco afetados e possam acompanhar a evolução da versão. Sem essa estratégia, as chances de falhas podem aumentar exponencialmente.

Distribuição

Monolíticos podem ser distribuídos, mas em Microservices, quando já existem uma grande quantidade de serviços, é preciso se preocupar muito mais com questões de latência de rede (não subestime a latência) e custos de serialização e desserialização, que podem tornar a resposta de um serviço mais lenta devido à necessidade da comunicação remota.

Mesmo depois de todos esses pontos, que são apenas algumas das desvantagens, não estou afirmando que a abordagem de Microservices é ruim. No entanto, é preciso avaliar a real necessidade do uso. Em geral, para aplicações com baixo nível de complexidade, a arquitetura monolítica pode funcionar melhor, pois em contexto que não precisa de excelente desempenho e ser escalável, há maior poder de resposta e os custos são bem menores.

No fim, a maior questão a ser avaliada é o fator custo-benefício. Que grandes diferenças e vantagens o uso de Microservices pode trazer (ou não) para sua organização? Deixe sua resposta nos comentários! Até a próxima.

***

Este artigo foi publicado originalmente em: https://www.concrete.com.br/2018/04/04/dificuldades-no-uso-de-microservices/