Microsserviços Antes da Hora: Quando Dividir Piora Tudo
Dividir o sistema cedo demais troca chamadas em memória por chamadas de rede e multiplica deploys, custos e pontos de falha. Por que modularizar o monolito antes de distribuir.
Renan Montanari
Engenheiro de Software Full-Stack
Introdução: A Promessa Que Custa Caro
A promessa é sedutora: dividir o sistema em serviços menores, cada time cuidando do seu pedaço, tudo escalando de forma independente.
Na apresentação, faz todo sentido. No dia a dia de quem dividiu cedo demais, o resultado costuma ser o contrário.
O Que Acontece Com Quem Dividiu Cedo Demais
Uma alteração simples passa a atravessar três serviços e exige três publicações coordenadas. Se uma delas atrasar, a feature inteira fica parada.
Quando algo quebra, a primeira pergunta vira: em qual dos doze serviços está o problema? Antes, bastava abrir os logs de uma aplicação.
Uma chamada que levava microssegundos virou uma chamada de rede. Ela pode falhar, demorar ou chegar duas vezes. Agora você precisa de timeout, retry e idempotência em lugares onde antes não existia nada disso.
E a conta da nuvem subiu, porque existem doze coisas rodando no lugar de uma. Cada uma com seu banco, seu deploy, seu monitoramento e sua configuração.
A Maioria Estava Resolvendo o Problema Errado
Microsserviço é, antes de tudo, uma solução organizacional.
Ele existe para que times diferentes consigam trabalhar sem pisar no pé um do outro e publicar em ritmos diferentes. A arquitetura acompanha a estrutura de pessoas. Quando isso não é verdade, a divisão cria custo sem criar benefício.
Se você tem um time, ou dois, esse problema geralmente não existe. O que existe é, na maioria das vezes, um monolito mal organizado. E a resposta para um monolito mal organizado é organizar o monolito.
Modularizar Antes de Distribuir
Separar por domínio dentro do mesmo sistema resolve quase tudo o que as pessoas procuram ao dividir:
- Fronteira clara entre responsabilidades
- Dono definido para cada parte do código
- Possibilidade de extrair depois exatamente a parte que precisar escalar sozinha
Um exemplo de estrutura modular dentro de um único projeto:
src/
├── billing/ # cobrança e faturamento
│ ├── api/ # interface pública do módulo
│ ├── domain/ # regras de negócio
│ └── infra/ # banco, gateways, filas
├── catalog/
│ ├── api/
│ ├── domain/
│ └── infra/
└── shared/ # só o que é realmente compartilhadoA regra que faz isso funcionar: um módulo só se comunica com outro pela interface pública dele. Nada de importar direto o repositório de outro domínio. Se essa regra for quebrada, a extração futura vai doer.
Ferramentas como lint de dependências ou regras de import ajudam a manter essa fronteira. Sem enforcement, a tendência natural é o acoplamento voltar.
A Ordem Importa
Monolito bem modularizado vira microsserviço com relativa tranquilidade. As fronteiras já existem, o contrato já está definido, e a extração é um trabalho de mover código e trocar uma chamada em memória por uma chamada de rede.
Monolito bagunçado vira doze serviços bagunçados. E aí a bagunça ficou distribuída, que é a versão mais cara dela. Agora ela atravessa rede, tem latência, e cada pedaço tem sua própria forma de falhar.
Trade-offs: Quando a Divisão Faz Sentido
Dividir não é sempre errado. Faz sentido quando há um motivo concreto:
| Situação | Faz sentido dividir? |
|---|---|
| Um módulo precisa escalar muito mais que o resto | Sim, pode ser extraído |
| Times diferentes publicam em ritmos muito diferentes | Sim, o motivo é organizacional |
| Parte do sistema tem requisitos de segurança ou conformidade distintos | Sim, isolar reduz superfície |
| "Porque parece moderno" | Não |
| "Para o sistema ficar mais organizado" | Não, isso se resolve modularizando |
Checklist Antes de Dividir
- Existe um módulo que precisa escalar, falhar ou ser publicado de forma diferente do resto?
- Já existe fronteira clara entre os domínios dentro do código atual?
- Outros módulos acessam o banco um do outro diretamente?
- Há times diferentes com dores reais de coordenação?
- Alguém vai operar, monitorar e pagar por cada serviço novo?
Se a resposta para a primeira pergunta for "nenhum", dividir só adiciona trabalho.
Conclusão: Uma Pergunta Antes da Decisão
Antes de dividir, pergunte: qual parte do meu sistema precisa escalar, falhar ou ser publicada de forma diferente do resto?
Se a resposta for nenhuma, a divisão não resolve nada. Ela só move a complexidade para a rede.
Organize o monolito primeiro. Quando uma fronteira realmente pedir para virar serviço, ela vai ser fácil de extrair.
Quer Revisar a Arquitetura do Seu Sistema?
Se você está avaliando dividir um sistema, ou já dividiu e está sofrendo com a complexidade, posso ajudar com:
- Diagnóstico arquitetural: onde estão as fronteiras reais e onde há acoplamento
- Modularização do monolito: organizar por domínio sem reescrever tudo
- Plano de extração: quando e como separar um serviço, se fizer sentido
Falar comigo