Monolitos Modulares vs Microsserviços: A Escolha Arquitetural da MSC Company
Por que a MSC adotou monolito modular em monorepo Bun em vez de microsserviços: transações ACID e entrega mais rápida.
O Encanto e a Armadilha dos Microsserviços Prematuros
Entre 2018 e 2023, a indústria de software global foi inundada pela narrativa de que qualquer empresa que pretendesse crescer precisava obrigatoriamente adotar uma arquitetura de microsserviços desde o primeiro dia. Inspiradas por gigantes como Netflix e Uber, centenas de equipes dividiram sistemas simples em dezenas de pequenos serviços independentes.
O resultado para a esmagadora maioria das empresas foi a criação do temido Monolito Distribuído:
- Latência de Rede Acumulada: Uma simples ação do usuário que antes levava 5ms em memória passou a disparar 8 requisições HTTP internas entre microsserviços, elevando a latência para mais de 300ms.
- Fim das Transações ACID Simples: Operações comerciais que precisavam debitar um saldo e atualizar um status passaram a exigir protocolos complexos de transações distribuídas (Two-Phase Commit ou Saga Pattern), multiplicando os pontos de falha e gerando inconsistências de banco.
- Custo Operacional de DevOps: Em vez de monitorar uma aplicação bem estruturada, a equipe passou a gerenciar dezenas de pipelines de CI/CD, clusters de Kubernetes caros e ferramentas complexas de service mesh.
Na MSC Company, guiados pelo princípio da simplicidade e da Constituição de Engenharia, adotamos uma postura pragmática: Monolito Modular por Domínio.
O Que é um Monolito Modular?
Um Monolito Modular combina o melhor dos dois mundos: a simplicidade de implantação e execução de um monolito com a disciplina de isolamento e fronteiras de domínio dos microsserviços.
Todo o código reside em um único monorepo estruturado, é implantado como uma unidade coesa na VPS gerenciada com Traefik, mas sua arquitetura interna é rigorosamente segmentada em módulos independentes baseados em Domain-Driven Design (DDD):
+-----------------------------------------------------------------------------------+
| ARQUITETURA DE MONOLITO MODULAR (MSC) |
| |
| [ Ingress / API Gateway (Elysia no Bun) ] |
| | |
| v (Chamadas de Função em Memória - Latência 0ms) |
| +-----------------------------------------------------------------------------+ |
| | MONOREPO COESO (Bun Workspaces) | |
| | | |
| | +-----------------------+ +------------------------+ +----------------+ | |
| | | Módulo: Atendimento | | Módulo: Faturamento | | Módulo: IA Core| | |
| | | - WhatsApp Webhook | | - Checkout & Assinatura| | - Prometheus | | |
| | | - Qualificação Leads | | - Emissão de Notas | | - RAG / Vector | | |
| | +-----------------------+ +------------------------+ +----------------+ | |
| | \ | / | |
| | v v v | |
| | +-----------------------------------------------------------------------+ | |
| | | Camada de Dados Unificada: PostgreSQL 16 + Drizzle ORM | | |
| | | (Schemas isolados por módulo sob a mesma transação ACID) | | |
| | +-----------------------------------------------------------------------+ | |
| +-----------------------------------------------------------------------------+ |
+-----------------------------------------------------------------------------------+
As Quatro Vantagens Práticas que Comprovamos em Produção
1. Chamadas em Memória com Latência Zero
Quando o módulo de Atendimento de WhatsApp precisa consultar as regras de precificação no módulo comercial, ele realiza uma chamada de função tipada em TypeScript. Não há serialização JSON, não há handshake TLS e não há risco de timeout de rede. A execução ocorre em microssegundos.
2. Transações ACID Reais com Drizzle ORM
Se uma operação de contratação de evento no Recanto do Açaí exige salvar o lead, reservar a data na agenda e gerar a cobrança, tudo pode ser envelopado em uma única transação do PostgreSQL 16:
await db.transaction(async (tx) => {
// 1. Cria o lead no módulo de atendimento
const lead = await leadModule.criarComTx(tx, dadosLead);
// 2. Reserva a data no módulo de eventos
await agendaModule.bloquearDataComTx(tx, lead.id, dataEvento);
// 3. Registra o contrato no módulo financeiro
await financeiroModule.gerarFaturaComTx(tx, lead.id, valorTotal);
});
// Se qualquer passo falhar, o rollback é 100% automático e consistente!
3. Refatoração Instantânea e Segurança de Tipos
Como todos os módulos compartilham o mesmo ecossistema TypeScript sob o runtime Bun, renomear uma propriedade ou alterar o contrato de um serviço atualiza instantaneamente todos os pontos do sistema no editor, prevenindo quebras em produção.
4. Deploy Unificado e Previsível
Um único comando de deploy no CI/CD compila e coloca toda a plataforma no ar em segundos, eliminando a necessidade de gerenciar versões cruzadas de múltiplos microsserviços.
Quando um Módulo Deve ser Extraído para um Serviço Separado?
Na MSC Company, não somos dogmáticos. Um módulo do monolito só é extraído para um serviço ou container isolado quando atende a critérios técnicos objetivos de hardware:
| Critério de Extração | Decisão Arquitetural | Exemplo Real na MSC |
|---|---|---|
| Exigência de Hardware Especial (GPU) | 🟢 Extrair para serviço dedicado | Modelos pesados de áudio/Whisper rodando em nós GPU |
| Picos Extremos e Assimétricos de CPU | 🟢 Extrair para worker assíncrono | Processamento de relatórios em lote via background jobs |
| Diferença de Ciclo de Vida da Equipe | 🟡 Avaliar caso a caso | Apenas se squads totalmente desacopladas operarem o código |
| Apenas "para organizar melhor o código" | 🔴 NUNCA extrair | Manter como módulo interno no Monolito Modular |
Perguntas Frequentes sobre Monolitos Modulares (FAQ AEO)
Um monolito modular não corre o risco de virar um código espaguete com o tempo?
Não, desde que a equipe implemente regras de lint e fronteiras estritas de importação. No nosso monorepo, um módulo só pode consumir funções públicas expostas pelo arquivo index.ts do módulo vizinho, sendo proibido importar arquivos internos ou acessar tabelas de outro domínio diretamente sem a camada de serviço autorizada.
Como o Monolito Modular escala quando o tráfego de usuários aumenta?
O monolito modular escala horizontalmente de forma trivial: basta iniciar múltiplas réplicas do mesmo container Docker atrás do proxy reverso Traefik. Como a aplicação não armazena estado em memória (stateless), o balanceamento de carga distribui as requisições perfeitamente.
É possível integrar agentes de IA autônomos em um Monolito Modular?
Sim. Nosso orquestrador multiagente Prometheus opera como um módulo central que acessa as ferramentas dos demais domínios via protocolos tipados em memória ou servidores MCP, garantindo velocidade máxima e governança centralizada.
Artigos Relacionados e Próximos Passos:
- Entenda nossa estratégia de dados em PostgreSQL: Fonte Única da Verdade Corporativa.
- Veja como estruturamos APIs velozes em Elysia vs FastAPI: Por Que Escolhemos Elysia no Bun.
- Conheça a camada de segurança em Segurança de Infraestrutura em VPS Própria: Traefik, TLS e Isolamento.
- Conheça nossas soluções tributárias em MSC Tax: Auditoria e Inteligência Fiscal.
- Quer simplificar e acelerar o desenvolvimento de software da sua empresa? Fale com os arquitetos da MSC Company.