A conversa sobre modernizar um monolito costuma começar pelo lugar errado: pela reescrita. Alguém propõe reconstruir o sistema em microsserviços, o projeto ganha um prazo de nove meses, e dezoito meses depois existem dois sistemas incompletos — o antigo, que ninguém quer mais tocar, e o novo, que ainda não atende tudo. Reescrita completa é a forma mais confiável de gastar muito e entregar pouco. Existe um caminho incremental, e ele começa sem quebrar nada.
Primeiro passo: conteinerizar sem dividir
O primeiro movimento não é separar o monolito. É empacotá-lo como está.
Isso parece pouco ambicioso e entrega muito mais do que se imagina: ambiente reprodutível, fim do "na minha máquina funciona", implantação previsível, possibilidade de subir várias instâncias, retorno rápido de versão anterior. Nada disso exige tocar na arquitetura da aplicação.
E, principalmente, é aqui que você descobre o que está realmente acoplado ao servidor. Um monolito que roda em container revela, em poucos dias, todas as suposições que ele fazia sobre a máquina: o arquivo que ele escrevia em disco local, a sessão que ele guardava em memória, a configuração que estava num arquivo editado à mão em produção. Cada uma dessas descobertas é um pré-requisito da divisão futura, e é bem melhor resolvê-las com o sistema inteiro do que no meio de uma extração.
Os pré-requisitos que a conteinerização revela
Antes de pensar em dividir, cinco coisas precisam estar resolvidas:
- Configuração externa. Nada de valor fixo no código ou em arquivo editado no servidor. Tudo por variável de ambiente ou serviço de configuração, com segredo em cofre.
- Aplicação sem estado. O processo pode ser morto e recriado a qualquer momento, sem perda. Isso implica sessão fora da memória local — em Redis ou em cookie assinado.
- Nada escrito em disco local. Upload de arquivo vai para armazenamento de objetos. Disco de container é efêmero por definição.
- Log na saída padrão, não em arquivo dentro do container. Coleta e retenção são responsabilidade da plataforma.
- Migração de banco desacoplada da subida da aplicação. Se a aplicação aplica migração ao iniciar, subir três instâncias simultaneamente é um problema. Migração é etapa própria do processo de implantação.
Esses cinco itens valem por si mesmos, mesmo que você nunca divida o monolito. É a maior parte do benefício por uma fração do esforço.
Achar as costuras certas
Monolito não se divide em qualquer lugar. A divisão boa acontece onde já existe uma fronteira natural, e há três sinais confiáveis:
- Acoplamento baixo com o resto. Um módulo que conversa com o núcleo por poucas chamadas bem definidas é candidato. Um módulo que compartilha dezenas de estruturas de dado não é.
- Perfil de escala diferente. Processamento de imagem que precisa de muita CPU em rajadas, dentro do mesmo processo que serve páginas web, é candidato óbvio — separar permite escalar cada um pelo que ele precisa.
- Ritmo de mudança diferente. Parte que muda toda semana acoplada a parte que muda uma vez por ano é atrito permanente de implantação.
E um sinal de que não é hora de dividir: se você não consegue descrever a fronteira sem usar "e também", a fronteira não existe ainda. Nesse caso, o trabalho é organizar o módulo dentro do monolito primeiro. Fronteira mal escolhida gera duas peças que precisam ser implantadas juntas — o pior dos dois mundos.
A ordem de extração que reduz risco
Comece pelo que é menos crítico e tem fronteira mais clara. Candidatos que costumam funcionar bem como primeira extração:
- Envio de notificação — e-mail, mensagem, notificação por aplicativo. Assíncrono por natureza, fronteira evidente, falha tolerável.
- Geração de documento ou relatório, que é pesado, esporádico e independente.
- Processamento de mídia, com perfil de recurso muito diferente do resto.
- Integração com terceiro, que já é uma fronteira externa.
O que não extrair primeiro: autenticação e o núcleo do domínio. São as partes mais acopladas e mais críticas, e errar ali custa caro. Elas ficam para quando a equipe já tiver experiência com o processo e com a operação distribuída.
| Etapa | O que fazer | Risco |
|---|---|---|
| 1 | Conteinerizar o monolito como está | Baixo |
| 2 | Resolver configuração, estado, log e migração | Baixo |
| 3 | Implantar rastreamento distribuído e métricas | Baixo |
| 4 | Extrair um serviço periférico e assíncrono | Médio |
| 5 | Extrair o segundo, já com o processo conhecido | Médio |
| 6 | Separar dados do serviço extraído | Alto |
| 7 | Reavaliar: vale continuar dividindo? | — |
A etapa 7 é a mais importante e a mais ignorada. Depois de duas ou três extrações, você tem dados reais sobre o custo operacional de cada serviço adicional. Muitas equipes descobrem, corretamente, que o ponto ideal é um monolito bem organizado mais três ou quatro serviços — e não trinta.
O banco de dados é a parte difícil
Extrair código é a parte fácil. O que realmente separa os serviços é o dado, e é aqui que a maioria das migrações para. O atalho tentador é manter o banco compartilhado: o serviço novo acessa as mesmas tabelas do monolito.
Isso funciona por um tempo e cria o pior resultado possível — o monolito distribuído. Você passou a ter a complexidade operacional de vários serviços e continuou com o acoplamento de um só: mudança de esquema quebra dois serviços, nenhum dos dois pode evoluir sozinho, e não há como implantar separadamente.
Caminhos que funcionam de verdade, do mais simples ao mais elaborado:
- O serviço extraído não acessa o banco direto. Ele pede ao monolito, por API. É um passo intermediário legítimo e resolve o acoplamento de esquema.
- Separar tabelas primeiro, dentro do mesmo banco. Definir que só um dos lados escreve em cada tabela, com o outro consultando por API. A separação lógica antecede a física.
- Escrita dupla temporária, durante a transição, com uma fonte de verdade clara e um mecanismo de reconciliação. Requer cuidado, porque escrita dupla sem reconciliação gera divergência silenciosa.
- Captura de mudanças do banco, publicando eventos que o novo serviço consome. É o caminho mais robusto para dado que precisa existir nos dois lados.
Observabilidade antes da divisão, não depois
Num monolito, depurar é ler um log e uma pilha de chamadas. Com serviços separados, uma requisição atravessa três processos, e sem rastreamento distribuído você fica sem saber onde o tempo foi gasto ou onde a falha começou.
A regra é simples: implante rastreamento distribuído antes da primeira extração, não depois de sentir falta. Junto com ele, identificador de correlação propagado entre serviços e log estruturado. É a etapa 3 da tabela por um motivo — sem ela, as etapas seguintes acontecem no escuro.
O custo que ninguém coloca na conta
Cada serviço novo traz uma parcela de custo permanente que não aparece no plano do projeto: mais um pipeline, mais um conjunto de alertas, mais uma dependência a versionar, mais uma peça no plano de recuperação, mais um lugar onde a autenticação entre serviços precisa funcionar.
Uma orientação prática de dimensionamento: se a sua equipe não tem gente suficiente para que cada serviço tenha alguém que o conheça bem, você tem serviços demais. Time de cinco pessoas operando quinze microsserviços passa mais tempo cuidando de infraestrutura do que entregando produto — e isso é o oposto do objetivo.
Monolito bem organizado, conteinerizado, com implantação automatizada e observabilidade decente é uma arquitetura perfeitamente respeitável. A divisão precisa ser justificada por um problema concreto — escala desigual, ritmo de mudança incompatível, autonomia de equipes —, não pela arquitetura ideal descrita numa apresentação.
Erros comuns
- Propor reescrita completa em vez de migração incremental.
- Dividir antes de resolver configuração, estado e log.
- Manter banco compartilhado entre monolito e serviço novo.
- Extrair primeiro a autenticação ou o núcleo do domínio.
- Dividir onde não há fronteira, criando duas peças que se implantam juntas.
- Deixar rastreamento distribuído para depois da primeira extração.
- Escrita dupla sem reconciliação, gerando divergência silenciosa.
- Migração de banco disparada pela subida da aplicação.
- Mais serviços do que a equipe consegue operar.
- Não reavaliar depois das primeiras extrações.
Onde a Solvefy/Cloud entra
Em consultoria DevOps, conduzimos essa migração pelo caminho incremental: conteinerizamos o que existe, resolvemos os pré-requisitos que aparecem, implantamos observabilidade e só então extraímos — começando pelo periférico, com o desenho de dados definido antes do código. E somos diretos quando a resposta é parar: para muitos clientes, o destino certo é um monolito bem empacotado com poucos serviços ao lado, não uma malha de microsserviços que a equipe não tem tamanho para operar.
Quer modernizar sem parar a operação? Fazemos um diagnóstico gratuito, sem compromisso, em solvefy.cloud.
Solvefy/Cloud — Infraestrutura que cresce com você.