Montar um ambiente local de microsserviços
Levantar um microsserviço em local é fácil: di-lo o seu README. O problema começa quando o fluxo que queres testar passa por quatro, e cada um chama outros dois que não são teus.
Esta página não é um tutorial de uma ferramenta concreta: é que peças fazem falta, porque a parte difícil não é a que parece, e como se resolve cada uma — com o Aseptic no fim, porque é o que este site documenta, mas os quatro problemas são os mesmos uses o que usares.
As quatro peças
Seção intitulada “As quatro peças”Um ambiente local que sirva para alguma coisa precisa de resolver quatro coisas. Nesta ordem de dificuldade real, que quase nunca é a ordem por que se abordam:
- Infraestrutura comum. Kafka, Redis, PostgreSQL, o que o teu sistema usar. É a parte mais visível e a mais resolvida: contentores.
- Arranque de cada serviço. O seu comando, o seu perfil, as suas variáveis, a sua porta. Trabalho repetitivo, mas mecânico.
- Comunicação entre serviços. Para onde chama cada um. É aqui que se vai a manhã, e é disto que quase ninguém fala.
- Dados. Um esquema criado e algo lá dentro com que testar.
1. A infraestrutura
Seção intitulada “1. A infraestrutura”Um docker-compose.yml com as peças comuns e docker compose up. É o que toda a gente
faz e está bem: os contentores são exatamente a ferramenta adequada para isto.
Dois detalhes que mordem mais tarde:
- As portas colidem. Cada equipa declara a 5432 e a 6379. Assim que tens dois projetos abertos, ou levantas e baixas, começam os conflitos.
- A infraestrutura partilha-se entre projetos, mas os dados não. Reutilizar o mesmo Postgres para dois sistemas diferentes acaba num esquema que ninguém sabe de quem é.
2. O arranque de cada serviço
Seção intitulada “2. O arranque de cada serviço”Cada serviço tem a sua forma: ./mvnw quarkus:dev,
./gradlew bootRun -Dspring.profiles.active=local, npm start, um binário. Com perfis,
variáveis e flags diferentes.
Isto é o que costuma acabar escrito num LOCAL_SETUP.md de quarenta passos: funciona, mas
envelhece mal. Ninguém atualiza o documento quando muda uma flag, e o seguinte que chega
descobre o desfasamento à força de erros.
Um detalhe que decide muito mais do que parece: nem todos os serviços querem correr da mesma maneira. Aquele em que estás a mexer queres nativo, com hot reload e com o depurador ligado. Os outros três só têm de estar de pé: em contentor estão bem, isolados e sem te sujarem a máquina.
3. A comunicação: a parte difícil
Seção intitulada “3. A comunicação: a parte difícil”Aqui está o trabalho a sério, e é o que nenhuma ferramenta de contentores te resolve.
O teu serviço bff chama o orders. Em produção esse URL vem da descoberta de serviços ou
do ingress. Em local, alguém tem de decidir para onde aponta, e as opções não são
equivalentes:
- Para o serviço levantado na tua máquina. É o que queres quando estás a mudar os dois lados. Mas então tens de o levantar também, com toda a sua cauda de dependências atrás.
- Para o ambiente partilhado de desenvolvimento. Poupa-te levantá-lo, em troca de ligação à sua rede, de dados que mudam debaixo dos teus pés e de que se esse ambiente estiver em baixo, tu também.
- Para um mock. Perfeito quando a resposta desse serviço te é indiferente, ou quando nem sequer lhe consegues chegar. Em troca de manter o stub.
O caro não é escolher: é aplicar a escolha. Cada opção significa mudar um URL na configuração de um repositório que não é teu, lembrares-te de não o comitares, e desfazê-lo quando quiseres testar outra coisa. Multiplica por serviços e por vezes ao dia.
E há uma armadilha: o URL correto depende de onde corre quem chama. Um serviço nativo
chega a um contentor por localhost:porta; um contentor que chama outro contentor, pelo
nome do serviço; e um contentor que chama algo nativo da tua máquina precisa do nome
especial do host. A mesma dependência, três URLs diferentes consoante como esteja a correr
cada extremo.
4. Os dados
Seção intitulada “4. Os dados”Esquema criado, migrações passadas e uns dados mínimos. Costuma resolver-se com as migrações da própria aplicação mais um script de semente.
A regra que convém não quebrar: o ambiente local não toca em bases de dados partilhadas. Uma migração lançada sem querer contra o ambiente de desenvolvimento comum é uma tarde perdida para toda a equipa.
As formas de o montar
Seção intitulada “As formas de o montar”| Abordagem | Boa para | Onde fica curta |
|---|---|---|
docker-compose de tudo |
Infraestrutura; um sistema pequeno e estável | Construir a imagem do teu serviço a cada mudança; sem hot reload nem depurador cómodos; a comunicação continua a ser configuração à mão |
Scripts + LOCAL_SETUP.md |
Começar depressa | Envelhece: ninguém o atualiza e falha de forma diferente em cada máquina |
| Testcontainers | Testes de integração a sério | O ambiente nasce e morre com o teste; não é um sítio onde trabalhar |
| Kubernetes local (Kind, minikube) | Parecer-se com produção | Muita máquina e muito ciclo de build para o dia a dia; o ciclo de mudança alonga-se |
| Orquestrador local | O ciclo diário com vários serviços | É preciso descrever cada serviço uma vez |
Nenhum é parvo: resolvem coisas diferentes e muitas vezes convivem. O que nenhum dos quatro primeiros faz é decidir por dependência para onde chama cada serviço e aplicá-lo sem tocar nos repositórios.
Como o Aseptic o resolve
Seção intitulada “Como o Aseptic o resolve”O Aseptic é um orquestrador de ambiente de trabalho que trata das quatro peças, e trata a terceira como o problema principal que é.
- Descreves cada serviço uma vez. Aponta para a pasta do repositório e a sua tecnologia, as suas portas, a infraestrutura de que precisa e a quem chama são autodetetadas. Revês e já está.
- Agrupas num cenário os serviços de um fluxo — «Checkout», «Registo de cliente» — e levantam-se juntos, por ordem e esperando que cada um esteja saudável.
- Por cada dependência escolhes local, nuvem ou mock, e o motor
reescreve o URL ao arrancar injetando-o como configuração
—flags
-Dou variáveis de ambiente—, com a perspetiva correta consoante onde corre cada extremo. Os teus repositórios não se tocam. - A infraestrutura comum (Kafka, Redis, PostgreSQL) é gerida pela app em Docker, com remapeamento automático de portas quando colidem.
- Cada serviço, nativo ou em contentor, à tua escolha: nativo aquele em que estás a mexer, em contentor os de fundo.
E o que montas partilha-se: um cenário exporta-se para um ficheiro autocontido, por isso
quem chega de novo clona, importa e arranca em vez de ler o LOCAL_SETUP.md.
Começar
Seção intitulada “Começar”- Instalar o Aseptic — é grátis e só precisas de Docker.
- O teu primeiro cenário em 5 minutos — os passos concretos.
- Mockar uma dependência — se o que te bloqueia hoje é não teres ligação à cloud.