Spring Cloud incubator has introduced a new project called Spring Cloud Circuit Breaker that provides a pluggable circuit-breaker interface. A circuit breaker defines a set of thresholds that when exceeded will halt the execution of a code block. This will help systems to fail fast and prevent cascading failures and system overload.
The Spring Cloud Circuit Breaker project is an abstraction layer across popular circuit breaker libraries in Java. The project currently supports Netflix Hystrix, Resilience4j, Sentinel, and Spring Retry.
Spring Cloud is an aggregation of common tools that can be used to build cloud-native distributed systems. Spring Cloud provides features for typical use cases like service registration and discovery, routing, load balancing, and circuit breakers. Until recently, the circuit-breaker functionality in Spring Cloud relied only upon Netflix Hystrix.
With the new Spring Cloud Circuit Breaker project, developers get the flexibility to pick other circuit-breaker implementations by coding against the circuit-breaker interface. To pick a specific implementation at runtime, one has to add the relevant starter JAR to the application’s classpath.
The following snippet shows how a products service can leverage the CircuitBreakerFactory API to create a CircuitBreaker and wrap calls to an external recommendations service inside the CircuitBreaker.
@Service
public static class ProductsService {
private RestTemplate rest;
private CircuitBreaker circuitBreaker;
public ProductsService(RestTemplate rest, CircuitBreakerFactory cbFactory) {
this.rest = rest;
this.circuitBreaker = cbFactory.create("recs");
}
public ProductList getProducts() {
return circuitBreaker.run(
() -> rest.getForObject("/recs", ProductList.class),
throwable -> "fallback");
}
}
The CircuitBreaker’s run method takes two arguments, a Supplier, and a fallback Function. The Supplier is used to wrap execution logic inside the CircuitBreaker. The fallback Function is used to specify the logic that should be executed when the CircuitBreaker trips.
Spring Cloud Circuit Breaker provides a reactive version in the form of the ReactiveCircuitBreakerFactory API. It can be used in applications built with the Reactor project. Here’s a snippet that showcases how a products service can use the reactive version of the CircuitBreaker to wrap calls to an external recommendations service:
@Service
public static class ProductsService {
private WebClient webClient;
private ReactiveCircuitBreaker circuitBreaker;
public ProductsService(WebClient webClient,
ReactiveCircuitBreakerFactory cbFactory) {
this.webClient = webClient;
this.circuitBreaker = cbFactory.create("recs");
}
public Mono<ProductList> getProducts() {
return circuitBreaker.run(
webClient
.get()
.uri("/recs")
.retrieve()
.bodyToMono(ProductList.class), throwable -> return Mono.just("fallback"));
}
}
The behavior of the circuit breakers can be configured using the Customizer bean interface. The Customizer can provide a default configuration for all circuit breakers and also provide specific configurations for individual circuit breakers.
Here’s a snippet that shows how to provide a default configuration for all circuit breakers backed by Resilience4j implementation:
@Bean
public Customizer<Resilience4JCircuitBreakerFactory> defaultCustomizer() {
TimeLimiterConfig timeLimiterConfig = TimeLimiterConfig
.custom()
.timeoutDuration(Duration.ofSeconds(4))
.build();
return factory ->
factory.configureDefault(id -> new Resilience4JConfigBuilder(id)
.timeLimiterConfig(timeLimiterConfig)
.circuitBreakerConfig(CircuitBreakerConfig.ofDefaults())
.build());
}
The Spring Cloud Circuit Breaker jars are currently available in the Spring snapshot repository. The project’s documentation describes the core concepts and the various configuration options.