Micro Serviços? Monolitos? Depois da conversa com o tipo chatgpt cheguei na ideia de Macro-Serviços
Disclaimer
Neste post não estou tentando denegrir as outras arquiteturas ou colocar Micro Serviços sobre Macro Serviços, Macro Serviços sobre Monólitos.
Ou qualquer tipo de coisa nesse sentido.
Hoje vim mostrar um pensamento aleatório de como um micro-serviço pode ser mais custoso de lidar do que um monólito e como podemos ir para um meio-termo antes de fazer migração total de arquitetura
Introdução
Todo mundo tá cansado de ouvir falar de AI, eu incluso.
Mas, jamais reclamaria da capacidade das LLM de fazer o método Investigativo com um modelo descente aka DeepSeek, aka Copilot, Llama e ChatGPT.
Por quê? Às vezes a forma que a LLM responde me dá vontade de explicitar coisas que eu não coloquei em contexto e de certa forma tentar ver mais do que consigo enxergar.
Então eu me questionei.
Por que Micro Serviços?
Porque precisamos isolar parte da lógica para atender diversas partes do código, permitindo que cada uma evolua de forma independente.
Isso ajuda a aumentar a performance em escala, possibilita a escalabilidade seletiva de serviços específicos (por exemplo, escalar apenas o serviço de pagamentos em datas comemorativas), melhora a resiliência a falhas (se um serviço falhar, os demais continuam funcionando) e facilita a manutenção ao permitir que equipes distintas trabalhem em diferentes serviços de maneira mais autônoma e coesa.
Porque Monólitos?
Porque é a mais fácil de manter (única codebase), mais simples de deployar, e mais fácil de testar de forma E2E.
No entanto, essa simplicidade cobra seu preço: é difícil escalar seletivamente — se apenas o módulo de checkout precisa de mais recursos, você ainda precisa escalar toda a aplicação — e mudanças em larga escala podem gerar efeitos colaterais imprevisíveis em módulos não relacionados.
A interdependência interna também torna mais desafiadora a adoção de múltiplas tecnologias ou a divisão de trabalho entre equipes especializadas. Tudo é escalado em conjunto.
Claro que aqui eu fiz um resumo muito absurdo que provavelmente foi parcial, sorry.
Mas o ponto que eu chego é que micro-serviços crescem e se expandem como uma praga já que uma vez que você começa a dividir um monólito você não sabe onde parar já que tudo começa a ter uma cara de serviço.
E tudo bem, mas 10 micro-serviços de User, Payments, Database, Replication, etc., começam a gerar mais ruído do que valor.
Essa fragmentação exagerada acarreta uma sobrecarga operacional significativa:
- múltiplos repositórios
- múltiplas pipelines de CI/CD
- múltiplas deployagens independentes
- múltiplos pontos de falha
Além disso, há uma sobrecarga cognitiva real — entender a arquitetura, fazer debugging entre serviços e garantir coesão funcional se torna um verdadeiro pesadelo, especialmente para times pequenos ou menos experientes.
Tanto para manter quando para entender para que tudo isso serve.
E nisso eu pensei porque não um Macro-Serviço
Contexualizando Macro-Serviço
É um micro-serviço grande apenas isso.
Mas aplicado ao famoso DDD (Domain-Driven Design), uma abordagem de design de software que foca em modelar a lógica de negócio com base em domínios reais, aproximando código e linguagem do problema do mundo real.
O DDD propõe organizar o sistema em torno de "bounded contexts" — contextos delimitados — que representam áreas específicas do negócio, promovendo maior coesão interna e clareza arquitetural.
Em vez de você pensar no micro-serviço, você começa a pensar no contexto do domínio em que o serviço vai ser utilizado.
Exemplo (grande nível): Netflix
E obviamente, vamos usar a Netflix de exemplo. Afinal todo grande exemplo tem que começar de algo insustentável.
Se fossemos construir uma Netflix do zero usando micro-serviços teriamos algo como:
Micro Serviço | Utilidade |
---|---|
video-catalog-service | Lista de vídeos e metadados |
recommendation-service | Sistema de recomendação |
transcoding-service | Conversão de vídeo |
user-profile-service | Dados do usuário |
auth-service | Login e sessão |
watch-history-service | Histórico de visualizações |
billing-service | Pagamentos e planos |
subtitle-service | Legendas |
drm-service | Proteção de conteúdo |
Mas se fossemos construir uma Netflix do zero usando macro-serviços teriamos algo como:
Macro Serviço | Utilidade |
---|---|
ContentDomain | Catálogo, metadados, transcodificação, legendas, DRM |
UserDomain | Perfil, histórico, login |
RecommendationDomain | Personalização, ranking, machine learning |
BillingDomain | Cobrança, assinatura, controle de acesso |
PlaybackDomain | Entrega de vídeo, qualidade adaptativa, telemetria |
Exemplo (nível menor): Lojinha do seu Zé
Se fossemos aplicar Micro-Serviços a lojinha do seu zé. Provavelmente teriamos algo como:
Micro Serviço | Utilidade |
---|---|
auth-service | login |
user-service | clientes |
product-service | produtos |
stock-service | estoque |
order-service | pedidos |
payment-service | integração com Pix |
report-service | relatórios |
notification-service | e-mails (que o Zé nem usa) |
Ok, isso ficou arquiteturalmente mais complexo do que deveria. Então usando Macro-Serviços teriamos
Macro Serviço | Utilidade |
---|---|
customer-domain | login, cadastro, dados do cliente |
sales-domain | pedidos, produtos, estoque |
finance-domain | pagamento via Pix e relatórios de venda |
Analise profunda
Veja que a ideia continua sendo a mesma, um serviço remoto sendo chamado por protocolo de rede a outra instância, preferencialmente em outra máquina. Essas comunicações geralmente utilizam tecnologias como REST, gRPC ou filas de mensagens (message queues), dependendo das necessidades de latência, complexidade e escalabilidade do sistema.
Mas temos algumas diferenças de contexto aqui.
O Micro Serviço tende fazer pequenas coisas por contexto, enquanto um Macro-Serviço quer controlar um dominio inteiro por contexto.
Isso tem vantagens e desvantagens e cada a analise profunda do sistema.
Critério | Monolito | Microserviço | Macroserviço |
---|---|---|---|
Complexidade Inicial | Baixa: uma única codebase, simples de entender | Alta: múltiplos repositórios, múltiplos deploys | Média: divisão por domínio, mas ainda modular |
Escalabilidade | Escala tudo ou nada | Escala apenas o necessário, independentemente | Escala por domínio (parcialmente granulado) |
Deploy e CI/CD | Único pipeline | Vários pipelines independentes | Pipelines por domínio (menos que micro, mais que mono) |
Desempenho Interno | Alto, sem chamadas de rede | Overhead por chamadas de rede e comunicação interserviços | Overhead moderado, menos granular |
Isolamento de Falhas | Falha pode afetar todo o sistema | Falhas isoladas por serviço | Isolamento por domínio |
Gerenciamento de Equipes | Difícil dividir equipe por responsabilidade | Times independentes por serviço | Times por domínio funcional |
Custo Operacional | Baixo para pequeno/médio porte | Alto: precisa de orquestração, observabilidade, monitoramento | Médio: menos serviços para orquestrar |
Manutenibilidade | Simples até crescer demais | Alto custo cognitivo | Melhor legibilidade e contexto |
Flexibilidade Tecnológica | Limitada a stack única | Pode variar stack por serviço | Stack por domínio, com controle melhor definido |
Curva de Aprendizado | Rasa | Íngreme | Média |
Velocidade de Desenvolvimento | Alta no início, cai com escala | Lenta no início, mais sustentável depois | Boa tração no início e manutenção decente ao escalar |
Conclusão
Esse aqui é o resultado do pensamento de um dia, feito graças a um vídeo do Augusto Galego (link abaixo). E que precisa ser estudado mais a fundo.
Minha recomendação pessoal é não ir direto a Macro ou Micro Serviços.
Comece com monolitos e veja se a mudança arquitetural é justificada ou não, ademais espero que tenham curtido esse post valeu.
Fonte: https://youtu.be/ooJjxNsQnK4