Olá, pessoal!
No post anterior, apresentei a visão geral do My Broker B3. Hoje vamos falar sobre a fundação que sustenta todo esse ecossistema: a infraestrutura.
Para um sistema de microserviços com essa complexidade, configurar manualmente cada banco de dados, broker de mensagens e ferramenta de monitoramento seria inviável. A solução foi usar Docker Compose para criar um ambiente local reproduzível que replica fielmente as necessidades de um sistema distribuído.
🗺️ O Mapa da Infraestrutura
O docker-compose.yml orquestra 12 containers organizados em 5 camadas:
┌─────────────────────────────────────────────┐
│ RELATIONAL LAYER (SQL) │
│ identity-db wallet-db order-db asset-db │
│ MySQL MySQL MySQL MySQL │
│ b3-core-db (PostgreSQL) │
├─────────────────────────────────────────────┤
│ NOSQL LAYER │
│ broker-mongodb (Mongo 6.0) │
├─────────────────────────────────────────────┤
│ CACHE LAYER │
│ broker-asset-cache b3-market-cache │
│ Redis Alpine Redis Alpine │
├─────────────────────────────────────────────┤
│ MESSAGING LAYER │
│ kafka (KRaft) rabbitmq (AMQP) │
├─────────────────────────────────────────────┤
│ OBSERVABILITY LAYER │
│ prometheus grafana │
└─────────────────────────────────────────────┘
🏗️ Decisão de Design: Isolamento por Domínio
A decisão mais importante da infraestrutura foi o isolamento de dados por domínio. Em vez de um banco monolítico, cada microserviço tem sua própria instância:
# Cada serviço tem seu próprio banco — falhas são isoladas
broker-identity-db:
image: mysql:8.0
ports:
- '3306:3306' # identity
broker-wallet-db:
image: mysql:8.0
ports:
- '3307:3306' # wallet
broker-order-db:
image: mysql:8.0
ports:
- '3308:3306' # orders
broker-asset-db:
image: mysql:8.0
ports:
- '3309:3306' # assets
b3-core-db:
image: postgres:15
ports:
- '5432:5432' # B3 core
Por que isso importa? Se o banco de ordens tiver um problema, o serviço de identidade continua funcionando. Falhas ficam isoladas no seu domínio.
📦 Cache: Instâncias Isoladas por Contexto
Dois Redis com propósitos distintos:
broker-asset-cache:
image: redis:7.0-alpine
ports:
- '${REDIS_BROKER_ASSET_PORT}:6379' # preços para a corretora
b3-market-cache:
image: redis:7.0-alpine
ports:
- '${REDIS_B3_MARKET_PORT}:6379' # preços para o matching engine
O b3-market-sync-api escreve no b3-market-cache e o b3-matching-engine-api lê dali para decidir se executa ou rejeita uma ordem. A separação garante que problemas na camada do broker não afetam a B3 e vice-versa.
📡 Mensageria: Dois Brokers, Dois Propósitos
Apache Kafka — Barramento Interno
Configurado no modo moderno KRaft (sem Zookeeper), mais leve e estável para desenvolvimento local:
kafka:
image: apache/kafka:3.7.0
environment:
KAFKA_PROCESS_ROLES: broker,controller
KAFKA_LISTENERS: EXTERNAL://0.0.0.0:9092,INTERNAL://0.0.0.0:29092,CONTROLLER://0.0.0.0:9093
KAFKA_ADVERTISED_LISTENERS: EXTERNAL://localhost:9092,INTERNAL://finance-kafka:29092
KAFKA_CLUSTER_ID: MkU3OEVBNTcwNTJENDM2Qk
Usado para os tópicos internos do ecossistema:
-
assets-market-data-v1— cotações de ativos -
order-events-v1— eventos de ciclo de vida das ordens
RabbitMQ — Integração Broker ↔ B3
rabbitmq:
image: rabbitmq:3-management
ports:
- '5672:5672' # AMQP
- '15672:15672' # Management UI
Usado exclusivamente para a comunicação entre a corretora e o simulador da B3:
-
mq-broker-to-b3— ordens enviadas para o matching engine -
mq-b3-to-broker— feedback de execução
Por que dois sistemas de mensageria? Kafka é ideal para streams de eventos com replay e múltiplos consumers. RabbitMQ é ideal para filas de trabalho com garantia de entrega ponto-a-ponto. Cada um onde faz mais sentido.
📊 Observabilidade desde o Dia 1
prometheus:
image: prom/prometheus:latest
volumes:
- ./config/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
ports:
- '9090:9090'
grafana:
image: grafana/grafana:latest
ports:
- '3000:3000'
Todos os microserviços Spring Boot exportam métricas via /actuator/health e /actuator/prometheus. O Prometheus coleta, o Grafana visualiza. Desde o primeiro serviço que sobe, já temos observabilidade.
🔐 Segurança: Sem Hardcode de Segredos
Toda configuração sensível fica em um arquivo .env (ignorado pelo Git):
# docker-compose.yml — apenas referências
broker-identity-db:
environment:
MYSQL_DATABASE: ${BROKER_IDENTITY_DB_NAME}
MYSQL_USER: ${BROKER_DB_USER}
MYSQL_PASSWORD: ${BROKER_DB_PASS}
MYSQL_ROOT_PASSWORD: ${BROKER_DB_ROOT_PASS}
Um .env.example é commitado como template, mas os valores reais nunca entram no repositório.
🚀 Como Executar
cp .env.example .env
# preencha as variáveis no .env
docker-compose up -d
Um único comando sobe os 12 containers. O ambiente de desenvolvimento é idêntico para qualquer pessoa que clone o repositório.
O que vem a seguir?
Com a infraestrutura no ar, o próximo post mostra o primeiro microserviço: o broker-market-data-api — um serviço Python que busca cotações reais na Brapi, persiste no MongoDB e publica no Kafka.
🔎 Sobre a série
⬅️ Post Anterior: Construindo um Ecossistema de Microserviços
➡️ Próximo Post: Integrador de Market Data: Consumindo Dados Reais com Python, MongoDB e Kafka
📘 Índice da Série: Guia da Série
Links:
Top comments (0)