Uma das arquiteturas mais estudadas, utilizadas e desejadas nos últimos anos, sem dúvida, é a de microservices, mas o resultado pode não ser exatamente aquilo que você esperava...
Se você perguntar para várias pessoas, talvez a maior parte delas irá ressaltar vantagens como escalabilidade, independência e divisão de responsabilidades como motivos suficientes para seguir por esse caminho.
No entanto, nada disso é garantido, e pior, se feito da forma errada o resultado pode ser catastrófico!
Até por isso muita gente tem voltado para uma arquitetura monolítica.
Se ao longo do dia a sua aplicação fica lenta ou até mesmo indisponível por conta do aumento da demanda de utilização, significa que ela provavelmente não é escalável.
Esse problema pode ser resolvido de forma vertical ou horizontal, ou seja, adicionando mais recursos, como CPU e memória, em uma mesma máquina ou simplesmente criando mais máquinas e distribuindo a demanda entre elas.
A forma mais simples sem dúvida é a vertical, mas ela favorece o desperdício desses recursos fora do pico enquanto na horizontal é possível simplesmente ir desligando as máquinas quando elas não forem mais necessárias...
A forma de escalar é exatamente a mesma, independente do tipo de arquitetura, seja ela monolítica ou de microservices.
No entanto, nem tudo se resume a escalar as máquinas de aplicação já que a maior parte delas utiliza bancos de dados ou APIs externas e conforme a demanda aumenta o gargalo vai se movendo.
O problema é que esses novos gargalos escalam de formas diferentes, ou nem mesmo estão no seu controle.
Escalar um banco de dados envolve uma estratégia completamente diferente, você pode simplesmente adicionar mais recursos, separá-los em escrita e leitura, criando várias réplicas de leitura, ter modelos projetados de leitura para relatórios e estatísticas, usar bancos de dados mais elásticos como o Aurora da AWS, é outra linha de raciocínio...
Novamente, ainda que o banco de dados também seja escalado nada impede que seu fornecedor limite a quantidade de requisições que você faz para a API dele e o gargalo vai seguir mudando de lugar...
A solução está na relação entre essas diferentes responsabilidades, se elas forem sempre síncronas, sempre irão impactar o tempo de resposta e pior, a disponibilidade da aplicação.
Introduzir filas, tornando os fluxos mais estratégicos assíncronos é quase sempre a melhor solução e isso se aplica em qualquer tipo de arquitetura.
Ter uma arquitetura de microservices totalmente síncrona escala menos que um único monolito, é mais frágil e também pode custar mais caro.
O mesmo se aplica à independência. Faça um teste, se você tirar um dos microservices do ar, os outros continuam funcionando normalmente?
Eles conseguem retomar o processamento quando voltarem? Isso permite que você faça deploy em qualquer hora do dia.
Se a resposta for não, talvez eles não sejam assim tão independentes...
Novamente o problema está na relação, no tipo de acoplamento entre eles, se ela for sempre síncrona, você talvez esteja apenas distribuindo um monolito, só que pior, usando a rede que é ordens de grandeza mais lenta do que simplesmente fazer uma chamada de método dentro do mesmo processo, da mesma máquina.
Isso não quer dizer que tudo precise ser assíncrono, aplique onde for mais estratégico ou demandar mais recursos.
Sem dúvida, um das vantagens de uma arquitetura de microservices é separar as responsabilidades, evitando o que o Domain-Driven Design chama de Big Ball of Mud.
Assim é possível escalar o time, distribuí-lo em diferentes bases de código, reduzir os conflitos de merge e trazer mais independência inclusive de tecnologia.
Isso é verdade, desde que seja feita uma modelagem estratégica eficiente, fazendo um entendimento profundo do domínio e de como fazer a divisão da forma mais coerente e independente possível.
Dividir no lugar errado pode criar equipes de tamanhos pouco uniformes, por exemplo, uma com 20 ou 30 pessoas e várias outras com 2 ou 3.
Além disso, se houver muito acoplamento entre eles boa parte do tempo da equipe pode ser desperdiçado apenas na integração, ao invés de ser investido na criação de valor de negócio, que é o que precisa ser entregue aos clientes.
Resumindo, nem tudo é o que parece ser, mais vale uma boa arquitetura monolítica, que pode sim fazer uso de fluxos assíncronos, de escalabilidade horizontal, de banco de dados elástico.
Na prática, a maior parte de nós já está em uma arquitetura distribuída e não se deu conta, afinal, quem não consome uma API externa?
Resolva os problemas com maturidade, conforme eles vão aparecendo e acima de tudo mensure os resultados como a produtividade da equipe, o tempo de resposta, quantidade de requisições atendidas por segundo, o custo de infraestrutura e inúmeras outras métricas que podem te mostrar se você está indo pelo melhor caminho.
Não existe certo e errado, bom, as vezes existe o errado, mas eu prefiro sempre olhar para as vantagens e desvantagens, lidando com elas da melhor forma possível.