Mastering Resilience4j: Real-World Spring Boot 3 Circuit Breaker Cases
This article explains why circuit breakers are essential for third‑party API calls, introduces the lightweight Resilience4j library, and provides step‑by‑step Spring Boot 3 examples—including Maven setup, RestTemplate and WebClient integrations, annotation usage, and both default and custom configurations—complete with code snippets and result screenshots.
Third‑party API calls are common but introduce stability, performance, and security risks; without a circuit‑breaker, failures can block threads, exhaust resources, and crash the application. Implementing a circuit‑breaker ensures graceful degradation and protects core functionality.
Resilience4j is a lightweight fault‑tolerance library inspired by Netflix Hystrix and designed for functional programming. It offers decorators such as circuit‑breaker, rate‑limiter, retry, and bulkhead that can be composed on any functional interface, lambda, or method reference.
1. Dependency Management
<code><dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-circuitbreaker-resilience4j</artifactId>
</dependency></code>2. RestTemplate Call Example
<code>@Service
public class CircuitService {
private final RestTemplate restTemplate;
private final CircuitBreakerFactory circuitBreakerFactory;
public CircuitService(RestTemplate restTemplate, CircuitBreakerFactory circuitBreakerFactory) {
this.restTemplate = restTemplate;
this.circuitBreakerFactory = circuitBreakerFactory;
}
public Object remoteService(Integer id) {
CircuitBreaker cb = this.circuitBreakerFactory.create("akk");
return cb.run(() -> this.restTemplate.getForObject(
"http://localhost:8088/demos/info/{id}", Map.class, id),
ex -> Map.ofEntries(
Map.entry("code", -1),
Map.entry("message", ex.getMessage())));
}
}
</code>The default timeout is 1 s; because the simulated endpoint sleeps for 3 s, the fallback response (code ‑1) is returned.
3. WebClient Call Example (Reactive)
<code>private final WebClient webClient;
private final ReactiveCircuitBreakerFactory reactiveCircuitBreakerFactory;
public CircuitBreakerService(WebClient webClient, ReactiveCircuitBreakerFactory reactiveCircuitBreakerFactory) {
this.webClient = webClient;
this.reactiveCircuitBreakerFactory = reactiveCircuitBreakerFactory;
}
public Mono<Map> reactiveInvoke(Integer id) {
return webClient.get()
.uri("/demos/info/{id}", id)
.retrieve()
.bodyToMono(Map.class)
.transform(it -> this.reactiveCircuitBreakerFactory.create("akk")
.run(it, ex -> Mono.just(Map.ofEntries(
Map.entry("code", -1),
Map.entry("message", ex.getMessage())))));
}
</code>The result image shows the same fallback behavior as the RestTemplate example.
4. Annotation‑Based Circuit Breaker
<code>@CircuitBreaker(name = "a-info", fallbackMethod = "infoFallback")
public Map<String, Object> info(Integer id) {
if (id == -1) {
throw new RuntimeException("非法数字");
}
return this.restTemplate.getForObject("http://localhost:8088/demos/info/{id}", Map.class, id);
}
public Map<String, Object> infoFallback(Integer id, Throwable e) {
return Map.of("code", -1, "message", e.getMessage(), "args", id);
}
</code>Configuration in application.yml :
<code>resilience4j:
circuitbreaker:
instances:
a-info:
minimum-number-of-calls: 10
</code>5. Circuit Breaker Creation and Configuration
Calling CircuitBreakerFactory#create creates a CircuitBreaker instance. The run method requires a Supplier (the protected call) and a Function (the fallback). If no fallback is needed, it can be omitted.
6. Default and Custom Configuration
Default settings can be overridden in the configuration file. For example, extending the timeout to 4 s:
<code>resilience4j:
timelimiter:
configs:
default:
timeout-duration: 4s
</code>After applying this change, a request that previously timed out at 1 s now succeeds within the 3 s simulated delay, as shown in the following screenshot.
7. Programmatic Custom Configuration for Specific Instances
<code>@Component
public class ReactiveCircuitBreakerCustomizer implements Customizer<ReactiveResilience4JCircuitBreakerFactory> {
@Override
public void customize(ReactiveResilience4JCircuitBreakerFactory factory) {
Consumer<Resilience4JConfigBuilder> config = cb -> {
cb.circuitBreakerConfig(CircuitBreakerConfig.custom().build());
cb.timeLimiterConfig(TimeLimiterConfig.custom()
.timeoutDuration(Duration.ofSeconds(4))
.build());
};
factory.configure(config, "akk", "a2");
}
}
</code>These examples demonstrate how to integrate Resilience4j into Spring Boot 3 applications, apply circuit‑breaker patterns with both imperative and reactive APIs, and fine‑tune behavior through annotations, YAML, or programmatic customizers.
Spring Full-Stack Practical Cases
Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.