💻 Exemplos: Capítulo 18: Resiliência e Circuit Breaker com Resilience4j
Especialização em Backend com Java & Spring Boot • Demonstrações Práticas Compiláveis
💻 Código de Exemplo 01 — Circuit Breaker com Fallback e Assinatura Compatível
package com.empresa.api.service;
import io.github.resilience4j.circuitbreaker.annotation.CircuitBreaker;
import org.springframework.stereotype.Service;
@Service
public class PaymentResilienceService {
@CircuitBreaker(name = "pagamentoService", fallbackMethod = "fallbackPagamento")
public String processarPagamento(Long pedidoId) {
if (pedidoId % 5 == 0) {
throw new RuntimeException("Gateway de pagamento fora do ar");
}
return "PAGAMENTO_APROVADO";
}
// Mesma assinatura de retorno + Throwable no final: contrato exigido pelo Resilience4j.
private String fallbackPagamento(Long pedidoId, Throwable t) {
return "PAGAMENTO_EM_PROCESSAMENTO_OFFLINE";
}
}
💻 Código de Exemplo 02 — Retry com Backoff Exponencial Combinado a Bulkhead
package com.empresa.api.service;
import io.github.resilience4j.bulkhead.annotation.Bulkhead;
import io.github.resilience4j.retry.annotation.Retry;
import org.springframework.stereotype.Service;
@Service
public class EstoqueConsultaService {
private int tentativas = 0;
@Retry(name = "consultaEstoque")
public boolean checarEstoque(Long produtoId) {
tentativas++;
System.out.println("Tentativa #" + tentativas + " de consulta de estoque...");
if (tentativas < 3) {
throw new RuntimeException("Timeout transitório na consulta de estoque");
}
return true;
}
// Isola no máximo 5 execuções concorrentes deste método, protegendo o pool
// de threads compartilhado de ser esgotado por relatórios pesados e lentos.
@Bulkhead(name = "relatoriosPesados")
public void gerarRelatorioMensal(Long lojaId) {
System.out.println("Processando relatório pesado da loja " + lojaId + " em pool isolado.");
}
}
💻 Código de Exemplo 03 — Monitoramento Programático do Estado do Circuit Breaker
package com.empresa.api.service;
import io.github.resilience4j.circuitbreaker.CircuitBreaker;
import io.github.resilience4j.circuitbreaker.CircuitBreakerRegistry;
import org.springframework.stereotype.Component;
@Component
public class CircuitBreakerMonitor {
private final CircuitBreakerRegistry registry;
public CircuitBreakerMonitor(CircuitBreakerRegistry registry) {
this.registry = registry;
// Reage em tempo real a transições de estado (ex.: disparar alerta ao abrir).
registry.getAllCircuitBreakers().forEach(cb ->
cb.getEventPublisher().onStateTransition(evento ->
System.out.println("Circuit Breaker '" + cb.getName() + "' mudou de " +
evento.getStateTransition().getFromState() + " para " +
evento.getStateTransition().getToState())));
}
public void listarEstadoAtual() {
registry.getAllCircuitBreakers().forEach(cb ->
System.out.println("Circuit Breaker " + cb.getName() + " Estado: " + cb.getState())
);
}
}