Skip to content

ec-ayrton/customCircuitBreaker

Repository files navigation

🔌 Custom Circuit Breaker - Resilience & Fault Tolerance (Java 8+)

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).


🌋 O Desafio

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 Solução Autônoma

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.


🏛️ Máquina de Estados do Disjuntor

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

2. Rodando os Testes

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

3. Analisando Resultados Reais do Terminal

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.

4. Considerações Finais & Escopo de Produção

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.

About

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).

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors