Modernização em fatias sem congelar o negócio
Como substituir um sistema legado por partes enquanto ele continua rodando, qual fatia tirar primeiro e as três condições que fazem o padrão falhar.
Toda substituição de sistema legado começa com a mesma proposta: congela o antigo, constrói o novo, vira num fim de semana. Isso quase nunca sobrevive ao contato com um negócio que precisa continuar vendendo na segunda.
O padrão strangler-fig é a alternativa. Você coloca uma camada de roteamento na frente do sistema legado, move uma capacidade por vez para trás dela e deixa o sistema antigo encolher até não sobrar nada que valha a pena manter no ar. O nome vem da figueira que cresce em volta da árvore hospedeira e acaba se sustentando sozinha.
O padrão é conhecido. O que se discute menos é qual fatia tirar primeiro e em que condições ele falha em silêncio.
A camada de roteamento é o truque inteiro
Nada funciona enquanto as requisições não puderem ir para um sistema ou outro sem que quem chama perceba. Isso significa uma fachada na frente da aplicação legada: um proxy reverso, um gateway de API ou um serviço fino que passa a ser dono do contrato público.
Duas propriedades importam mais do que a tecnologia escolhida:
- O roteamento é por capacidade, não por usuário. Mandar uma porcentagem dos usuários para o sistema novo significa que os dois sistemas passam a ser donos do mesmo dado ao mesmo tempo. Isso é um projeto de reconciliação de dados fantasiado de migração.
- A fachada é dona do contrato. Se os clientes ainda chamam o sistema legado diretamente para qualquer coisa, ele não pode ser aposentado. Cada chamador direto que passar despercebido vira mais um ano de vida do sistema antigo.
Qual fatia tirar primeiro
O instinto é começar pela coisa menos arriscada. Isso costuma estar errado, porque a coisa menos arriscada também é a que prova menos.
Classifique as fatias candidatas em quatro eixos. A primeira deve pontuar bem nos quatro, não brilhantemente em um.
| Eixo | O que você quer primeiro | Por quê |
|---|---|---|
| Razão leitura/escrita | Predominância de leitura | Um caminho de leitura pode rodar nos dois sistemas e ser comparado sem corromper nada. |
| Posse dos dados | Dona das próprias tabelas | Escrita compartilhada nas mesmas tabelas a partir de duas bases de código é o modo de falha que encerra esses projetos. |
| Visibilidade no negócio | Visível, não crítica | Ganho invisível não compra fôlego para a segunda fatia. Ganho crítico torna a primeira falha fatal. |
| Frequência de mudança | Em evolução ativa | Uma capacidade que ninguém toca não tem força motriz. Ela fica meio migrada para sempre. |
Na prática isso costuma significar relatórios, busca, notificações ou uma visão de leitura voltada ao cliente. Raramente significa faturamento, e quase nunca significa autenticação.
Rodar os dois, comparar, depois virar
Para um caminho de leitura, a virada mais segura não é uma virada. É um período em que os dois sistemas respondem e só uma resposta é entregue.
- A fachada manda a requisição para o sistema legado e devolve a resposta dele.
- Em paralelo, manda a mesma requisição para o serviço novo e descarta a resposta.
- Registra onde os dois discordam.
- Quando a discordância cai a zero, ou a um conjunto de diferenças que você aceitou explicitamente, você troca qual resposta é devolvida.
Isso custa uma chamada duplicada por requisição e compra algo que nenhuma suíte de testes dá: prova contra tráfego real de produção, incluindo as entradas que ninguém documentou.
As três condições que fazem falhar
O padrão não falha por tecnologia. Ele falha por três motivos, e dá para verificar os três antes de escrever qualquer código.
Ninguém é dono de aposentar o sistema antigo. Se o orçamento da migração é medido em funcionalidades entregues, os últimos 20% do legado nunca somem, porque as fatias restantes são as feias. Agora você roda dois sistemas para sempre e paga pelos dois. Faça da aposentadoria de um componente legado nomeado o critério de conclusão de cada fatia, e não da entrega do novo.
O banco é compartilhado e continua compartilhado. Duas aplicações gravando nas mesmas tabelas não é um estado intermediário, é um acoplamento permanente sobre o qual os dois lados vão construir. Se a fatia não puder ser dona dos seus dados, ou escolha outra fatia ou aceite uma camada anticorrupção como a entrega de verdade e pare de chamar isso de migração.
O time que conhece o legado não participa. Comportamento não documentado é a maior parte do que um sistema de vinte anos faz. As pessoas que sabem quais flags importam são justamente as que o projeto está substituindo, o que é um problema de governança antes de ser de engenharia. Reserve o tempo delas explicitamente, e pague por ele.
O que medir
Três números dizem se a migração avança ou apenas acumula código:
- Endpoints legados ainda alcançáveis diretamente, sem passar pela fachada. Deve tender a zero. Se não tender, nada jamais poderá ser aposentado.
- Componentes legados de fato aposentados, não "migrados". Migrado significa que o novo existe. Aposentado significa que o antigo foi apagado.
- Fatias em andamento, que deveriam ser uma ou duas. Cinco fatias a 70% é pior do que uma a 100%, porque cada fatia inacabada mantém viva uma dependência legada.
Se esses três números não estão num painel que alguém lê todo mês, a migração está rodando no otimismo.
Quando não usar
O padrão se paga quando o sistema legado precisa continuar rodando e a substituição vai levar mais de um trimestre. Se o sistema é pequeno o bastante para ser reescrito em seis semanas, a fachada, a comparação em sombra e a operação dupla são puro custo. Reescreva e vire.
Ele também não se aplica quando o problema é o modelo de dados, e não o código. Embrulhar um esquema ruim num serviço novo produz um serviço novo com esquema ruim. Isso é uma migração de dados com um projeto de aplicação anexado, e deve ser planejada como tal.
É assim que trabalhamos em projetos de modernização, e as mesmas regras sobre posse e acesso a dados aparecem nas nossas práticas de engenharia e segurança.