divisão do monólito
Monólito para microsserviços: o primeiro serviço fora em 20 dias
Onze anos de commits em um deployment único, quatrocentas tabelas em um schema, um trem de release que parte uma vez por trimestre. Descobrimos onde os dados de fato se separam, dividimos o schema primeiro e extraímos um serviço que compila, sobe e chama o plantão sozinho. Rails, Django, Spring, .NET, PHP ou Go: o método é o mesmo, e o segundo serviço é mais rápido porque a parte difícil já ficou para trás.
20 dias para o primeiro serviço, mais rápido no segundo
Dois serviços e uma biblioteca. O número de serviços deveria bater com o número de times capazes de carregar um pager por eles.
Um deployment
Um repositório, um schema, um trem de release, imports que andam em círculo.
- one deployable11 years of commits
- shared schema400+ tables
- release trainquarterly
- circular importscycles
Dividido
Dois serviços com schemas próprios, uma biblioteca para o que é compartilhado, deployments separados.
- billingGo · own schema
- catalogueGo · own schema
- shared kernellibrary
- deploysper service
20 dias para o primeiro serviço, mais rápido no segundo
Como o trabalho anda
- 01dias 1–4
Achar as costuras nos dados
Os logs de query mostram quais tabelas são lidas juntas na mesma requisição. É ali que estão as fronteiras, diga o que disser a estrutura de pacotes.
- 02dias 3–8
Separar o schema primeiro
Dividir as tabelas e remover os joins que cruzam a fronteira enquanto tudo ainda é um deployment só. A maior parte do risco vive neste passo, e nesta altura ainda é reversível.
- 03dias 8–15
Extrair um serviço
O que tem menos dependências de entrada, que raramente é o que mais irrita as pessoas. Ele sobe atrás da mesma interface até operá-lo deixar de ser interessante.
- 04dias 14–20
Dar a ele um pipeline próprio
Repositório próprio, deployment próprio, escala de plantão própria. Um serviço cujos releases ainda precisam ser coordenados com o monólito não ganhou nada para você, e isso aparece no décimo quinto dia em vez de no fim.
O que a plataforma faz e o que uma pessoa faz
| O que a plataforma faz e o que uma pessoa faz | Quem faz | Notas |
|---|---|---|
| Mapear coacesso de tabelas e acoplamento de módulos | Plataforma | A partir dos logs de query e do grafo de chamadas, por um período longo o bastante para incluir o fechamento do mês. |
| Propor as costuras | Os dois | A plataforma ordena os candidatos. Uma pessoa confere contra as fronteiras dos seus times. |
| Quebrar os joins que cruzam a fronteira | Plataforma | Trabalho mecânico, revisado como pull request, entregue em pedaços pequenos. |
| Escolher que serviço vai primeiro | Engenheiro | A propriedade do time decide isso com mais frequência do que o código. |
| Fronteiras de transação | Engenheiro | Onde uma transação de banco cruzava a costura, alguém precisa decidir o que acontece em caso de falha. |
| CI, deployment e plantão | Os dois | Um serviço sem pipeline e escala próprios é um módulo com saltos de rede extras. |
Quem corta a costura
Dezenas de migrações, mais de dez anos em sistemas construídos por gente que já foi embora e divisões suficientes para saber quais compensam. Monólitos em Rails, Django, Spring, .NET, PHP e Go, schemas com quatrocentas tabelas e uma década de joins cruzando fronteira. A costura nunca está onde o diagrama de arquitetura diz, e achar a de verdade é a maior parte do que você está comprando.
A primeira extração é o teste, e ela é delimitada: um serviço, schema próprio, deployment próprio, em produção. Você tem uma resposta que funciona pelo preço de uma fase.
Perguntas que engenheiros fazem
- Com quantos serviços devemos terminar?
- Menos do que o diagrama da apresentação de arquitetura. Extraia um, rode em produção por um trimestre e então decida sobre o próximo. Times que planejam doze de antemão costumam chegar a quatro e a muito banco compartilhado.
- Precisamos reescrever em Go?
- Não. Extrair e reescrever são decisões separadas, e muitas divisões ficam na linguagem original. Onde a gente reescreve um serviço, é porque aquele módulo seria reescrito de qualquer forma, morasse onde morasse.
- O que acontece com o código compartilhado?
- Ele vira uma biblioteca versionada com superfície pequena. Quando o núcleo compartilhado começa a crescer a cada sprint, esse é o sinal de que a costura ficou no lugar errado, e movê-la ainda dentro do projeto é muito mais barato que no segundo ano.
- Dá para fazer isso enquanto entregamos features?
- Dá, e vai ficar mais lento por causa disso. O passo a proteger é a separação do schema: intercalar trabalho de feature ali é como esses projetos empacam por um ano com o banco dividido pela metade.
- E aquele banco compartilhado do qual todo mundo avisa?
- É por isso que o schema vai primeiro. Dois serviços sobre um schema são um monólito distribuído com modos de falha piores que os do ponto de partida, e é a forma mais comum de esse trabalho ser feito mal.
Comece por uma extração
Tamanho, cadência de release e o que está forçando a mudança bastam para uma primeira resposta. Voltamos com onde as costuras parecem estar e o que o primeiro serviço exigiria.
Um engenheiro responde, e a primeira pergunta normalmente é sobre a sua cadência de release.