DEV Community

Roberto de Vargas Neto
Roberto de Vargas Neto

Posted on • Edited on • Originally published at dev.to

Infraestrutura como Código: Subindo o ecossistema financeiro com Docker Compose

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        │
└─────────────────────────────────────────────┘
Enter fullscreen mode Exit fullscreen mode

🏗️ 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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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'
Enter fullscreen mode Exit fullscreen mode

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}
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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)