Este projeto foi desenvolvido como um desafio de engenharia de software voltado para resiliência de sistemas distribuídos e tolerância a falhas. Ele implementa o padrão de arquitetura Circuit Breaker (Disjuntor) customizado, protegendo a aplicação contra falhas em cascata ao integrar com serviços externos instáveis (como Gateways de Pagamento).
Em ecossistemas de microsserviços, quando uma dependência externa (API de terceiros, banco de dados ou Gateway) fica lenta ou cai, as requisições locais começam a se acumular, travando os pools de threads do servidor de aplicação. Isso causa um efeito dominó que derruba todo o sistema.
A implementação deste projeto introduz um mecanismo inteligente de interrupção de fluxo (Fast-Fail). Utilizando estruturas de dados puramente atômicas e thread-safe (AtomicReference e AtomicInteger), o disjuntor monitora a taxa de erros na integração e bloqueia chamadas desnecessárias a serviços fora do ar, dando tempo para a dependência externa se recuperar.
O componente gerencia o fluxo de execução baseado em três estados rígidos (CircuitState):
+---------+ >= 3 Falhas Consecutivas +---------+
| | -------------------------> | |
====> | CLOSED | | OPEN |
| (Saudável) | <------------------------- | (Inativo)|
+---------+ 3 Sucessos Seguidos +---------+
^ |
| | Passados 10 segundos
| v
| +---------+
+-------------------------------- | HALF- |
| OPEN |
+---------+
(Testando Fluxo)
1. **`CLOSED` (Fechado - Fluxo Normal):** O sistema está estável. As requisições passam direto para o Gateway de pagamento. Se ocorrerem **3 falhas consecutivas**, o circuito muda para `OPEN`.
2. **`OPEN` (Aberto - Curto-Circuito):** O Gateway externo é considerado fora do ar. Qualquer tentativa de requisição é rejeitada imediatamente (`Fast-Fail`) com um status `HTTP 503 Service Unavailable`, sem sequer tentar tocar a rede. O circuito permanece assim por um timeout de recuperação de **10 segundos**.
3. **`HALF_OPEN` (Entreaberto - Teste de Carga):** Após os 10 segundos, o circuito entra em modo de testes, permitindo um limite estrito de **3 requisições** de sondagem. Se **todas as 3 obtiverem sucesso**, o circuito volta para `CLOSED`. Se **uma única falhar**, o disjuntor reabre imediatamente para o estado `OPEN`.
---
## 🛠️ Componentes do Projeto
* **`CustomCircuitBreaker` (Infraestrutura):** Classe core responsável pelo controle de estado concorrente. Utiliza concorrência fina e não-bloqueante para gerenciar os contadores e timestamps de transição.
* **`CircuitController` (API Endpoint):** Expõe a rota de processamento simulado de pagamentos:
* `POST /api/v1/payment/process?forceFailure=true`: Força uma falha de comunicação com o Gateway externo para testar o comportamento de abertura do circuito.
* `GET /api/v1/payment/status`: Consulta em tempo real o estado atual da máquina de estados do disjuntor.
---
## 🏃♂️ Como Executar os Testes de Carga com K6 (Ambiente Linux)
Para validar a transição automática de estados sob estresse concorrente, utilizamos o **Grafana K6**.
### 1. Instalação do K6 no Linux (Ubuntu/Debian)
Execute os comandos abaixo no seu terminal para adicionar o repositório oficial e instalar a ferramenta:
```bash
sudo gpg --no-default-keyring --keyring /usr/share/keyrings/k6-archivekeyring.gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys C5AD17C747E3415A3642D57D77C6C491D6AC1D69
echo "deb [signed-by=/usr/share/keyrings/k6-archivekeyring.gpg] [https://dl.k6.io/deb](https://dl.k6.io/deb) stable main" | sudo tee /etc/apt/sources.list.d/k6.list
sudo apt-get update
sudo apt-get install k6
Certifique-se de que a aplicação Spring Boot está rodando localmente na porta 8080. Abra o seu terminal, navegue até a pasta raiz do projeto (onde está o seu script JavaScript de teste) e execute:
Bash
k6 run bucket-carga.js
Ao fim da simulação de estresse, o relatório do terminal demonstrará com precisão o ganho arquitetural do padrão:
Proteção de Threads (http_req_failed): Durante o período em que o circuito muda para OPEN, o K6 mapeará as requisições barradas pelo disjuntor com HTTP 503. Isso indica que a aplicação se auto-protegeu, recusando tráfego danoso sem consumir I/O.
Fast-Fail de Sub-Milissegundo: Ao analisar os tempos de resposta (http_req_duration), as requisições que bateram no circuito OPEN retornam em microsegundos. O servidor web não desperdiça tempo esperando timeouts de rede de conexões que ele já sabe que vão falhar.
Embora a implementação atual utilize o controle de estados acoplado à injeção direta no CircuitController, este modelo foi adotado estritamente para fins didáticos e de experimentação prática de arquitetura.
Em um cenário real de produção corporativa, esse comportamento seria desacoplado através de:
1 - AOP (Aspect-Oriented Programming): Utilização de anotações personalizadas (ex: @CustomCircuitBreaker) via interceptores de métodos do Spring AOP, encapsulando a lógica de negócio em proxies e separando o código de resiliência das regras de aplicação.
2 - Bibliotecas de Mercado: Para aplicações reais em larga escala que exigem recursos avançados como métricas no Prometheus/Grafana e janelas de tempo deslizantes (Sliding Window Custom Metrics), costuma-se estender soluções maduras de mercado como o Resilience4j.