Introdução
Gostaria de compartilhar um pouco da minha experiência nesse tipo de atividade com vocês. Primeiramente, tenha em mente que não há nada pior que isso, e o caos é iminente. Tudo que antes parecia simples e trivial passa a não ser mais.Aquele seu
IMemoryCache
precisará avisar outras aplicações, e outros conceitos, como IDistributedCache
, terão que ser aplicados. Aquela transação talvez agora não seja mais possível, e você terá que abrir mão disso. Você vai criar ódio da infra e das falhas de rede, que antes passavam despercebidas. Vai começar a usar o Redis com mais frequência, filas sobre filas, e o ambiente começa a crescer. Sua instalação e manutenção ficarão cada vez mais complexas.
Então, pense bem antes de seguir esse caminho sem volta. Vou listar abaixo as vantagens e desvantagens dessa arquitetura:
Vantagens e Desvantagens
Prós:
Contras:
- Altamente escalável e distribuído.
- Atualização (GMUD) de processos específicos sem impactar operações críticas.
- Permite que várias equipes (squads) trabalhem com mais liberdade para resolver problemas.
- Uso de diversas tecnologias pode ser muito útil — ao trocar a tecnologia, tarefas difíceis podem se tornar simples e rápidas em alguns cenários. (Mas cuidado com a famosa “colcha de retalhos”!)
Contras:
- Mais tempo de desenvolvimento.
- Gerenciamento do ambiente é bem mais difícil e complexo.
- Seus testes (TDD) integrados agora serão mais complexos e trabalhosos.
- Você precisará de recursos adicionais como filas, servidores de cache, proxies etc., que antes não eram necessários.
- Controle de versões de API e comunicação entre serviços: antes, se você removia algo no monolito, o projeto nem compilava, acusando o que faltava na interface. Agora, não tem mais isso — e depois de um tempo, será impossível saber se alguém ainda usa aquela versão da API… até que você desligue e alguém grite. ("Ah, mas pode documentar e tal..." Vai por mim, é conversa.)
Recomendação
Muitas vezes, quando dou consultoria em empresas, simplesmente separar o sistema atual em módulos já resolve 90% dos problemas. Mas quando realmente a arquitetura de microsserviços é a melhor opção? Na minha opinião, quando você realmente precisa escalar uma aplicação, não terá como fugir. Mas tenha em mente que estamos falando de milhares de acessos ao seu sistema o tempo todo, ou de grandes gargalos em processos específicos, com muita gente trabalhando ao mesmo tempo. Nesse cenário, afirmo com toda certeza: essa arquitetura salva a lavoura.Escuto muito coisas do tipo:
"Ah, mas e se um dia eu precisar escalar? Já não é melhor desenvolver assim desde o início?"
Sou categórico em afirmar: não. Prefira o monolito no início. Existem partners e boas práticas que ajudam a estruturar seu sistema de forma que torne a separação mais simples no futuro. Algumas práticas que considero excelentes:
Boas práticas para um monolito
Separe em módulos:Escreva o monolito de forma modular. Sempre que possível, separe as regras de negócio. Se, por acaso, mudar de ideia no meio do caminho — para agrupar ou desagrupar módulos — isso será bem mais simples, e o refactoring vai te salvar.
Banco de dados:
Agrupe as tabelas por módulo. Se puder deixá-las em bancos separados, melhor ainda. Se não, use schemas para separar os módulos — isso facilitará sua vida no futuro.
Sempre escuto:
"Ah, Lucio, não dá... o cliente, o produto, a hierarquia de usuários... usamos em vários módulos!" Sim, isso vai acontecer. Uma maneira simples e eficiente de resolver isso, de forma imediata, é com views. Crie, por exemplo, uma view cliente no schema do módulo, apenas com os campos que ele usa. Nunca acesse diretamente os schemas de outros módulos.
Dependência entre módulos:
Sempre que possível, utilize uma interface no seu módulo para representar a dependência. Injete a classe do outro módulo que implementa essa interface. Tome muito cuidado para não sair referenciando outros módulos alucinadamente. Quando o acoplamento estiver muito forte, reavalie suas fronteiras. No monolito, isso fica bem visível e é fácil de resolver.
Com esses simples cuidados, sua vida ao escalar uma aplicação se tornará bem mais simples.