CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-io-quarkus--quarkus-smallrye-fault-tolerance

Build fault-tolerant network services

Pending
Overview
Eval results
Files

circuit-breaker-strategies.mddocs/

Circuit Breaker Strategies

Circuit breaker patterns that prevent cascading failures by monitoring failure rates and temporarily blocking calls to failing services. Provides automatic failure detection, recovery mechanisms, and named circuit breaker instances for shared state.

Capabilities

Basic Circuit Breaker

Standard circuit breaker functionality with configurable failure thresholds, delays, and recovery logic.

@CircuitBreaker(
    requestVolumeThreshold = 20,
    failureRatio = 0.5,
    delay = 5000,
    delayUnit = ChronoUnit.MILLISECONDS,
    successThreshold = 1,
    failOn = {IOException.class, TimeoutException.class},
    skipOn = {IllegalArgumentException.class}
)
public ReturnType protectedMethod() throws Exception;

Parameters

  • requestVolumeThreshold - Minimum requests before failure evaluation (default: 20)
  • failureRatio - Failure ratio to open circuit (0.0-1.0, default: 0.5)
  • delay - Time before transitioning from open to half-open (default: 5 seconds)
  • delayUnit - Time unit for delay (default: MILLIS)
  • successThreshold - Successful calls needed to close from half-open (default: 1)
  • failOn - Exception types considered failures (default: Throwable.class)
  • skipOn - Exception types not considered failures (takes precedence)

Circuit Breaker States

  • Closed: Normal operation, calls pass through
  • Open: Calls immediately fail without execution
  • Half-Open: Test calls allowed to check service recovery

Usage Example

@ApplicationScoped
public class PaymentService {
    
    // Payment processing with circuit breaker
    @CircuitBreaker(
        requestVolumeThreshold = 10,
        failureRatio = 0.3,
        delay = 30000,
        successThreshold = 3
    )
    @Fallback(fallbackMethod = "processPaymentOffline")
    public PaymentResult processPayment(PaymentRequest request) throws PaymentException {
        return paymentGateway.process(request);
    }
    
    public PaymentResult processPaymentOffline(PaymentRequest request) {
        // Queue payment for later processing
        return paymentQueue.enqueue(request);
    }
    
    // External service with aggressive circuit breaker
    @CircuitBreaker(
        requestVolumeThreshold = 5,
        failureRatio = 0.2,
        delay = 60000,
        failOn = {ConnectException.class, SocketTimeoutException.class},
        skipOn = {ValidationException.class}
    )
    public ExternalApiResponse callExternalService(ApiRequest request) {
        return externalApiClient.call(request);
    }
}

Named Circuit Breakers

Named circuit breaker instances that share state across multiple methods or classes.

@CircuitBreakerName("shared-circuit-breaker")
@CircuitBreaker(requestVolumeThreshold = 10, failureRatio = 0.4)
public ReturnType namedCircuitBreakerMethod();

// Multiple methods sharing the same circuit breaker state
@CircuitBreakerName("database-circuit")
public ReturnType firstDatabaseMethod();

@CircuitBreakerName("database-circuit") 
public ReturnType secondDatabaseMethod();

Usage Example

@ApplicationScoped
public class DatabaseService {
    
    // All database operations share the same circuit breaker
    @CircuitBreakerName("database-operations")
    @CircuitBreaker(requestVolumeThreshold = 15, failureRatio = 0.3)
    public List<User> findUsers(UserQuery query) throws SQLException {
        return userRepository.find(query);
    }
    
    @CircuitBreakerName("database-operations")
    @CircuitBreaker(requestVolumeThreshold = 15, failureRatio = 0.3)
    public void saveUser(User user) throws SQLException {
        userRepository.save(user);
    }
    
    @CircuitBreakerName("database-operations")
    @CircuitBreaker(requestVolumeThreshold = 15, failureRatio = 0.3)
    public void deleteUser(Long userId) throws SQLException {
        userRepository.delete(userId);
    }
}

@ApplicationScoped
public class OrderService {
    
    // Order service also uses the same database circuit breaker
    @CircuitBreakerName("database-operations")
    @CircuitBreaker(requestVolumeThreshold = 15, failureRatio = 0.3)
    public List<Order> findOrders(OrderQuery query) throws SQLException {
        return orderRepository.find(query);
    }
}

Circuit Breaker with Fallback

Combined circuit breaker and fallback patterns for complete resilience.

@CircuitBreaker(requestVolumeThreshold = 10, failureRatio = 0.5)
@Fallback(fallbackMethod = "fallbackMethod")
public ReturnType protectedMethodWithFallback();

@CircuitBreaker(requestVolumeThreshold = 5)
@Fallback(value = CustomFallbackHandler.class)
public ReturnType protectedMethodWithHandler();

Usage Example

@ApplicationScoped
public class WeatherService {
    
    @Inject
    CacheService cache;
    
    // Weather API with circuit breaker and cached fallback
    @CircuitBreaker(
        requestVolumeThreshold = 8,
        failureRatio = 0.4,
        delay = 20000
    )
    @Fallback(fallbackMethod = "getCachedWeather")
    @Timeout(5000)
    public WeatherData getCurrentWeather(String city) throws WeatherServiceException {
        return weatherApiClient.getWeather(city);
    }
    
    public WeatherData getCachedWeather(String city) {
        WeatherData cached = cache.get("weather:" + city);
        if (cached != null) {
            return cached.withStaleIndicator();
        }
        return WeatherData.unavailable(city);
    }
    
    // Stock quote service with handler-based fallback
    @CircuitBreaker(requestVolumeThreshold = 5, failureRatio = 0.6)
    @Fallback(value = StockQuoteFallbackHandler.class)
    public StockQuote getStockQuote(String symbol) throws QuoteServiceException {
        return stockApiClient.getQuote(symbol);
    }
}

public class StockQuoteFallbackHandler implements FallbackHandler<StockQuote> {
    
    @Inject
    HistoricalDataService historicalData;
    
    @Override
    public StockQuote handle(ExecutionContext context) {
        String symbol = (String) context.getParameters()[0];
        // Return last known quote or estimated quote
        return historicalData.getLastKnownQuote(symbol)
            .orElse(StockQuote.estimated(symbol));
    }
}

Circuit Breaker Monitoring

Integration with metrics and health checks for circuit breaker monitoring.

// Circuit breaker with custom name for monitoring
@CircuitBreakerName("payment-gateway")
@CircuitBreaker(requestVolumeThreshold = 20, failureRatio = 0.25)
public PaymentResult processPayment(PaymentRequest request);

// Accessing circuit breaker state programmatically
CircuitBreakerRegistry registry;
CircuitBreaker circuitBreaker = registry.circuitBreaker("payment-gateway");
CircuitBreaker.State state = circuitBreaker.getState();

Usage Example

@ApplicationScoped
public class SystemHealthService {
    
    @Inject
    CircuitBreakerRegistry circuitBreakerRegistry;
    
    @Inject
    MeterRegistry meterRegistry;
    
    public HealthCheckResponse checkCircuitBreakerHealth() {
        List<String> openCircuits = new ArrayList<>();
        
        // Check all named circuit breakers
        for (String name : circuitBreakerRegistry.getAllCircuitBreakerNames()) {
            CircuitBreaker cb = circuitBreakerRegistry.circuitBreaker(name);
            if (cb.getState() == CircuitBreaker.State.OPEN) {
                openCircuits.add(name);
            }
        }
        
        if (openCircuits.isEmpty()) {
            return HealthCheckResponse.up("circuit-breakers")
                .withData("status", "All circuit breakers closed")
                .build();
        } else {
            return HealthCheckResponse.down("circuit-breakers")
                .withData("open-circuits", openCircuits)
                .build();
        }
    }
    
    @EventObserver
    public void onCircuitBreakerStateChange(CircuitBreakerStateChangeEvent event) {
        // Record metrics when circuit breaker state changes
        Counter counter = Counter.builder("circuit.breaker.state.changes")
            .tag("name", event.getCircuitBreakerName())
            .tag("from", event.getFromState().toString())
            .tag("to", event.getToState().toString())
            .register(meterRegistry);
        
        counter.increment();
    }
}

Advanced Circuit Breaker Patterns

Complex patterns combining circuit breakers with other fault tolerance strategies.

Retry with Circuit Breaker

@Retry(maxRetries = 3, delay = 1000)
@CircuitBreaker(requestVolumeThreshold = 10, failureRatio = 0.5)
@Timeout(5000)
public ReturnType resilientMethod();

Bulkhead with Circuit Breaker

@Bulkhead(value = 5, waitingTaskQueue = 10)
@CircuitBreaker(requestVolumeThreshold = 15, failureRatio = 0.4)
public ReturnType isolatedMethod();

Usage Example

@ApplicationScoped
public class CriticalService {
    
    // Maximum resilience combination
    @Retry(maxRetries = 2, delay = 500)
    @CircuitBreaker(
        requestVolumeThreshold = 12,
        failureRatio = 0.3,
        delay = 45000
    )
    @Timeout(8000)
    @Fallback(fallbackMethod = "criticalFallback")
    @Bulkhead(value = 3)
    public CriticalData performCriticalOperation(String operationId) throws Exception {
        return criticalSystemClient.execute(operationId);
    }
    
    public CriticalData criticalFallback(String operationId) {
        // Emergency fallback - might return cached data or trigger manual process
        return emergencyDataSource.getCriticalData(operationId);
    }
}

Types

Circuit Breaker Core Types

// Circuit breaker states
enum CircuitBreakerState {
    CLOSED,    // Normal operation
    OPEN,      // Calls blocked
    HALF_OPEN  // Testing recovery
}

// Circuit breaker registry for programmatic access
interface CircuitBreakerRegistry {
    CircuitBreaker circuitBreaker(String name);
    Set<String> getAllCircuitBreakerNames();
}

// Circuit breaker instance
interface CircuitBreaker {
    State getState();
    Metrics getMetrics();
    String getName();
    
    enum State {
        CLOSED, OPEN, HALF_OPEN, DISABLED, FORCED_OPEN
    }
}

Circuit Breaker Metrics

// Circuit breaker metrics
interface CircuitBreakerMetrics {
    int getNumberOfSuccessfulCalls();
    int getNumberOfFailedCalls();
    int getNumberOfBufferedCalls();
    int getNumberOfSlowCalls();
    float getFailureRate();
    float getSlowCallRate();
    Duration getSlowCallRateThreshold();
}

Event Types

// Circuit breaker events for monitoring
interface CircuitBreakerEvent {
    String getCircuitBreakerName();
    ZonedDateTime getCreationTime();
    
    enum Type {
        SUCCESS, ERROR, IGNORED_ERROR, STATE_TRANSITION,
        RESET, DISABLED, FORCED_OPEN_STATE
    }
}

// State change event
interface CircuitBreakerStateChangeEvent extends CircuitBreakerEvent {
    CircuitBreaker.State getFromState();
    CircuitBreaker.State getToState();
}

Install with Tessl CLI

npx tessl i tessl/maven-io-quarkus--quarkus-smallrye-fault-tolerance

docs

asynchronous-strategies.md

bulkhead-strategies.md

circuit-breaker-strategies.md

configuration.md

fallback-strategies.md

index.md

programmatic-api.md

rate-limiting-strategies.md

retry-strategies.md

timeout-strategies.md

tile.json