Diário de Dev #12 — Hardening de WebSockets, Bypass de Cloudflare na VPS e Visualização 3D com ClojureScript
Período: 06 de Junho a 13 de Junho de 2026
Esta semana foi extremamente intensa em termos de infraestrutura, arquitetura de rede e interfaces interativas. Trabalhei em três frentes: estabilizei a captura de dados em tempo real da minha aplicação de trading, portei meus scrapers em Clojure para rodarem de forma autônoma em uma VPS contornando o Cloudflare, e criei uma visualização interativa tridimensional sobre ecossistemas Clojure.
Aqui está o relato técnico, as decisões tomadas e o que aprendi.
🌎 Segunda & Terça-Feira (08/06 - 09/06): A Recursão do Clojure Dialects Globe
Iniciei a semana construindo um novo projeto: o Clojure Dialects Globe. A tese é recursiva: construir uma visualização interativa sobre a versatilidade de compilação da linguagem Clojure, escrita em Clojure em todas as camadas da aplicação.
O objetivo é plotar 39 dialetos da linguagem Clojure em um globo terrestre 3D, posicionando o marcador geográfico no país de origem do criador do dialeto e definindo o tamanho do marcador proporcionalmente à sua quantidade de estrelas no GitHub.
A Arquitetura do Projeto (clj-dialects)
Para cobrir todo o espectro (scripts, backend, web e mobile), estruturei o projeto em 4 camadas:
- Babashka (Scripts): Script fetch_stars.bb que lê o arquivo de metadados (
base.edn), consulta a API do GitHub e atualiza a contagem de estrelas de cada dialeto. - Clojure JVM (API Backend): Um servidor web Jetty leve rodando na porta 3000, servindo as informações via Transit-JSON (um formato de transmissão mais otimizado que JSON bruto).
- ClojureScript + Three.js (Web Frontend): O motor tridimensional usando Three.js r175 sob Reagent (React para Clojure). Adicionei shaders GLSL customizados para a atmosfera da Terra, estrelas de fundo e renderização dinâmica dos sprites.
- ClojureDart + Flutter (Mobile): Protótipo estruturado para rodar a mesma interface tridimensional no mobile através do Flutter.
Desafio Técnico Superado: O Globo Azul sem Textura
Ao atualizar as bibliotecas do Three.js, a textura foto-realista da Terra (NASA) parou de carregar, exibindo apenas um globo azul genérico.
- Causa: O Three.js r155+ alterou o tratamento de espaço de cores de texturas no canvas, exigindo a definição explícita do
colorSpaceparaSRGBColorSpace. - Solução (ClojureScript):
;; Correção de espaço de cores no carregamento da textura (let [tex (.load (THREE/TextureLoader.) "textures/earth.jpg")] (aset tex "colorSpace" (.-SRGBColorSpace THREE)) tex)
🛜 Quarta-Feira (10/06): Hardening de WebSockets e Ingestão com OKX
No meu projeto principal de trading, o ark-streams, enfrentei um problema invisível e clássico de engenharia de redes: conexões de WebSocket que travavam sem fechar ou disparar erros no Go, deixando a interface vazia de dados de mercado (empty streams).
A Causa: Ausência de Read Deadlines
Em conexões de longa duração, roteadores intermediários ou firewalls estaduais podem dropar a conexão de forma silenciosa (idle timeout). Se a sua aplicação não tenta ler ativamente com um tempo limite (ReadDeadline), a goroutine de leitura fica bloqueada indefinidamente no buffer TCP.
A Solução: ws_keepalive
Centralizei o ciclo de vida de conexão em um helper genérico ws_keepalive.go:
- Configurei um timer de keepalive que redefine o
ReadDeadlineantes de enviar o ping correspondente. - Se o servidor falhar em retornar o pong correspondente ou dados novos dentro do intervalo de tolerância, a conexão é fechada ativamente pelo cliente e entra em ciclo de reconexão automática.
// ws_keepalive.go - Exemplo prático de enforcement
conn.SetReadDeadline(time.Now().Add(readDeadline))
conn.SetPongHandler(func(string) error {
conn.SetReadDeadline(time.Now().Add(readDeadline))
return nil
})
Ingestor: Migração forçada Binance → OKX
Como o servidor de produção roda nos EUA, a API da Binance retornava erro HTTP 451 (bloqueio geográfico). Migrei toda a captura de liquidações, contratos em aberto (OI) e taxas de captação (funding rate) para o WebSocket da OKX, adaptando os parsers e as suítes de teste.
🚀 Quinta-Feira (11/06): CI/CD, NATS Mirrors e deploy-vps.sh
Com a ingestão corrigida, automatizei o deploy. Substituí scripts baseados em systemd locais por uma imagem Docker enxuta e um pipeline completo de CI/CD:
- Compilação e Armazenamento: GitHub Actions compilam a imagem de Go + frontend Svelte e armazenam no repositório seguro GHCR (GitHub Container Registry).
- Deploy via Runner: Um runner self-hosted escuta por commits na master, executa deploy-vps.sh que limpa instâncias órfãs e recria os contêineres usando o docker-compose.
- NATS Overlap Fix: Configurei os streams históricos permanentes como mirrors de
MARKET_DATAno JetStream, eliminando erros de colisão de subject overlap.
🛡️ Sexta-Feira (12/06): O Bypass de Cloudflare via Xvfb e Executor Quant
Na sexta-feira, dividi as atividades entre os dois projetos centrais.
Scrapers Clojure na VPS (techsentry) e a Batalha contra o Cloudflare
Queria rodar meus crawlers de preços de notebooks (OLX, AliExpress) da VPS Oracle. No entanto, o Cloudflare bloqueava acessos puros via HTTP/curl disparados por IPs conhecidos de datacenters.
- A Descoberta: O Cloudflare bloqueia o fingerprint TLS de requests puros, mas tolera navegadores Chrome normais com interface ("headed") mesmo sob IPs de nuvem.
- A Solução: Instalei o Chromium snap na VPS e o utilizei sob o comando
xvfb-run -a(X Virtual Framebuffer), criando uma tela virtual na memória do Linux para que o Chromium rodasse pensando que tinha uma interface física de vídeo disponível. - O Cloudflare aceitou a navegação e permitiu a extração total de dados.
- Sync Git: Corrigi um erro histórico na sincronização do repositório da VPS instalando chaves SSH exclusivas como Deploy Keys de leitura no GitHub.
O Executor Quant (Gate 3 Concluído)
Finalmente, finalizei o módulo do executor algorítmico automatizado no Go. Implementei o riskguard.go que atua como barreira entre o sinal recebido e o envio de ordens na Bitget:
- Checks de Segurança: O sinal deve expirar se for mais velho que o candle correspondente (
MAX_SIGNAL_AGE_MS); a corretagem para se o feed estiver sem updates por mais de 15 segundos (MAX_DATA_STALENESS_MS); e um circuit breaker local no banco de dados KV bloqueia novas operações se houver perda diária superior a 3%.
🛠️ Tecnologias, Conceitos e Conceitualização da Semana
Para facilitar a organização e indexação do meu blog, mapeei as principais tecnologias, padrões e metodologias que utilizei ativamente na prática esta semana:
1. Linguagens & Runtimes
- Go (Golang): Implementação do executor de ordens e lógica concorrente do
RiskGuard(canais, contexts e structs de controle). - Clojure (JVM & Babashka): Desenvolvimento de servidores de API REST e scripts Babashka (
fetch_stars.bb) para enriquecimento rápido de dados do GitHub. - ClojureScript: Criação de WebGL interactives e controle reativo de estados de UI sob shadow-cljs e Reagent/React.
- ClojureDart & Dart/Flutter: Estruturação multiplataforma para o aplicativo mobile e desktop do globo e especificações do Prompt-IDE.
- Python: Desenvolvimento do script de Walk-Forward Analysis (
walkforward.py) para simulação e teste out-of-sample das otimizações das estratégias.
2. Infraestrutura, Redes & DevOps
- NATS JetStream (e KV Store): Utilização de streams persistentes duráveis para o track record de ordens, mirrors para replicação estável, e a Key-Value Store nativa do NATS para controle de estado e kill-switch resiliente a restarts.
- Docker & Docker Compose: Criação de contêineres e otimização de contextos de compilação via cache de layers e arquivos
.dockerignore. - CI/CD Automático: Configuração de GitHub Actions (publicando imagens no GHCR) e automatização de deploys contínuos em um runner self-hosted na VPS.
- Oracle Cloud Infrastructure (OCI): Utilização de VPS ARM de alta performance para execução dos robôs e extração distribuída.
- Virtual Framebuffer (Xvfb): Emulação gráfica na memória RAM do Linux para execução de navegadores gráficos sem monitor físico (
xvfb-run -a).
3. Engenharia de Redes & Concorrência
- Bypass de Cloudflare: Estudo de assinaturas e fingerprints de TLS/HTTP, migrando de requisições cruas HTTP para instâncias Chromium headed sob Xvfb.
- Controle de Timeout TCP: Implementação de
ReadDeadlineeWriteDeadlineno pacote de sockets do Go para prevenir timeouts ocultos e sockets zumbis. - Idempotência em 3 Camadas: Garantia contra re-entrega de eventos por meio de hashes determinísticos, logs locais em KV e IDs determinísticos na Bitget (
ClientOID). - Garantias de Entrega: Lógica At-Least-Once no JetStream exigindo Acks explícitos das mensagens consumidas.
4. Finanças Quantitativas
- Indicadores Técnicos (Alligator, MFI, ATR, BB Squeeze, Awesome Oscillator): Implementação de algoritmos matemáticos para sinalização e tomada de decisões.
- Walk-Forward Analysis (WFA): Metodologia de validação rolling de estratégias de trading com divisão rígida in-sample/out-of-sample.
📜 Registro Completo de Commits (Histórico Git da Semana)
Para manter a fidelidade e o registro dos dados reais do blog, aqui está o log exato de todos os commits realizados durante a semana nos três repositórios principais:
1. Repositório: ark-streams
ec2e61c- feat(executor): Gate 3 completo — executor automatizado com shadow mode e documentação de fusão.cd5836c- fix(docker): exclude go.work from build context — remove referências aonexus-desktopno contexto de build do contêiner.54890ec- perf(docker): cache Go deps separately — cache de dependências em layer separada para acelerar compilações Docker.af9674f- fix(cicd): remove LIQUIDATIONS from smoke test — correção de teste de fumaça dependente de mercado para mirror streams.88699b0- fix(cicd): opt into Node.js 24 for GitHub Actions — migração preventiva do workflow do Node.js.0a0f06e- feat(cicd): full CI/CD pipeline — setup de GitHub Actions, publicação de imagem no GHCR e CD via runner self-hosted na VPS.0ac7555- docs(ops): track bastion-connect.sh — documentação de SSH bastion e tunnel setup.17edef7- fix(deploy): replace broken systemd deploy — migração para deploy dockerizado automático via scriptdeploy-vps.sh.9146c8c- ui: overhaul high-contrast theme — remodelagem visual de alto contraste no Svelte e fix de mark price.b06fc49- fix(analysis): compact AggressorEngine checkpoint — compactação de serialização para respeitar o payload máximo do NATS JetStream.b8989be- fix(streams): create archive streams as mirrors — resolução de subject overlaps de streams históricos de market data.b6d45d2- fix(collector): enforce read deadlines + heartbeat — aplicação de keepalives e limites temporais em WebSockets.0e86028- fix(collector): use Bitget's literal "ping" — correção de heartbeat específico do WS Bitget.051cb9c- feat(collector): replace Binance funding/OI/aggtrade feeds with OKX — novos coletores OKX.d2e2232- feat(collector): replace Binance liquidation feed with OKX — novo parser de liquidações OKX.1501742- fix(nexus-desktop): local timezone + expand history to 7d — melhorias visuais de exibição de histórico.12ff5a9- feat(nexus-desktop): portrait monitor layout — suporte a split vertical para monitores em formato retrato.
2. Repositório: techsentry (TechSentry)
4774a020- feat: iPhone enrich no ciclo da VPS — nova flag--enrich-iphonespara enriquecimento de dados de busca.90ace35d- feat: modo --gc no jar — ativação de Garbage Collector programático de Datahike no jar de produção.8461b249- chore: scripts de diagnóstico e GC — limpeza e indexação interna do banco Datahike.65551359- fix: scan-vps.sh usa TECHSENTRY_DB_PATH relativo — caminho do banco de dados ajustado para portabilidade.dfbd7bfc- fix: scan-vps.sh garante /usr/local/bin no PATH — ajuste para consistência do cron daemon na VPS.128ccaec- fix: scan-vps.sh sem --clobber no release download — compatibilidade com a CLI do GitHub v2.4.0.5bd16741- feat: CI/CD com VPS como runner de scan via uberjar — automação completa do ciclo de execução remota de jars.e60737be- Merge branch 'feat/vectra-monitor' — consolidação do monitoramento de ofertas.ec3aa9da- chore: scripts de diagnóstico CDP/cookie OLX — validação de controle do browser real.d31a3eb0- feat: OLX enricher com Chrome real não-headless — bypass de bloqueios Cloudflare.3f3b47ef- docs: sync VPS↔GitHub resolvido — setup e deploy de chaves Deploy Keys e sonda OLX versionada.066f51d3- docs: relatório da missão de scraping na VPS nexus — documentação inicial da infraestrutura de crawls na VPS.
3. Repositório: clj-dialects (Clojure Dialects Globe)
4b086ec- feat(flutter): minimal working app — aplicativo ClojureDart integrado para busca e consumo de estado da API.e9a7cab- chore(ci): setup stable github pages deployment — automação de deploy estático do globo web no GitHub Pages.f1c4ce0- feat(mobile): ClojureDart Flutter implementation — código base mobile Dart/Clojure.cf7fbbb- feat(web): implement 3d globe visualization using Three.js — o motor tridimensional WebGL do globo.1ae9dab- chore: initial project structure — setup de dependências e banco de dados de dialetosbase.edn.
💡 Lições da Semana
- Navegadores Headed no Linux Headless: Usar
xvfb-runcom Chromium configurado para evitar detecção de automação (AutomationControlleddesativado) é a tática definitiva para crawlers rodarem em VPS sem sofrer bloqueio automático. - Network timeouts são obrigatórios: Nunca confie em conexões TCP persistentes sem implementar explicitamente keepalives e read-deadlines a nível de aplicação.
- Immutabilidade de Sinais: Construir o executor baseado em idempotência de hashes determinísticos (
SignalID = strategy-symbol-tf-time-action) garante que mesmo em caso de crash e re-entrega de eventos (at-least-once do JetStream), o robô nunca executará a mesma ordem duas vezes.
📅 Próxima Semana
- Executar os testes em modo sombra (Shadow Mode) na VPS por pelo menos 14 dias para mapear latência de sinal e desvios de PnL por drift de preços.
- Acompanhar os logs cron de extração do OLX via Chromium sob display virtual na VPS.
- Melhorar o filtro e busca de ecossistemas na visualização 3D de dialetos do Clojure.