Renan Montanari Blog
Voltar ao blog
ArquiteturaMicrosserviços

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

Renan Montanari

Engenheiro de Software Full-Stack

7 min de leitura

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 compartilhado

A 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çãoFaz sentido dividir?
Um módulo precisa escalar muito mais que o restoSim, pode ser extraído
Times diferentes publicam em ritmos muito diferentesSim, o motivo é organizacional
Parte do sistema tem requisitos de segurança ou conformidade distintosSim, 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

Vamos revisar sua arquitetura →

Gostou? Compartilhe