In a microservices architecture, service-to-service communication is common. However, it introduces the risk of cascading failures when one service goes down. To address this, we use Resilience4j, a lightweight fault tolerance library inspired by Netflix Hystrix.
In this post, we’ll explore:
- What is a Circuit Breaker?
- Introduction to Resilience4j
- Integrating Resilience4j Circuit Breaker in Spring Boot
- Fallbacks, Retry, and Rate Limiter
- Configuration and Monitoring

π§© What is a Circuit Breaker?
A Circuit Breaker is a design pattern used to detect failures and encapsulate the logic of preventing a failure from constantly recurring during maintenance, outages, or system overloads.
Circuit Breaker States:
- Closed: Requests flow normally.
- Open: All requests are blocked immediately.
- Half-Open: Some requests are allowed to test if the service has recovered.
When failures exceed a threshold, the breaker “opens” to prevent further damage.
π What is Resilience4j?
Resilience4j is a fault tolerance library built for Java 8+ and functional programming. It provides:
- CircuitBreaker
- Retry
- RateLimiter
- TimeLimiter
- Bulkhead
- Cache
Lightweight and easy to integrate with Spring Boot.
βοΈ Add Resilience4j to Your Project
Maven Dependency
io.github.resilience4j
resilience4j-spring-boot3
Add Spring Boot Starter Web
org.springframework.boot
spring-boot-starter-web
ποΈ Project Structure
com.kscodes.springboot.microservice
β
βββ controller
β βββ ProductController.java
βββ service
β βββ ProductService.java
βββ exception
β βββ FallbackHandler.java
βββ Application.java
π₯οΈ Service with Circuit Breaker
β
ProductService.java
package com.kscodes.springboot.microservice.service;
import io.github.resilience4j.circuitbreaker.annotation.CircuitBreaker;
import org.springframework.stereotype.Service;
import java.util.Random;
@Service
public class ProductService {
@CircuitBreaker(name = "productServiceCB", fallbackMethod = "fallbackForProduct")
public String getProductInfo(String productId) {
if (new Random().nextBoolean()) {
throw new RuntimeException("Simulated service failure");
}
return "Product Info for ID: " + productId;
}
public String fallbackForProduct(String productId, Throwable throwable) {
return "Fallback: Product service is currently unavailable. Please try later.";
}
}
β
ProductController.java
package com.kscodes.springboot.microservice.controller;
import com.kscodes.springboot.microservice.service.ProductService;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/products")
public class ProductController {
private final ProductService productService;
public ProductController(ProductService productService) {
this.productService = productService;
}
@GetMapping("/{id}")
public String getProduct(@PathVariable String id) {
return productService.getProductInfo(id);
}
}
βοΈ Resilience4j Configuration in application.yml
resilience4j:
circuitbreaker:
instances:
productServiceCB:
registerHealthIndicator: true
slidingWindowSize: 5
failureRateThreshold: 50
minimumNumberOfCalls: 5
waitDurationInOpenState: 10s
permittedNumberOfCallsInHalfOpenState: 2
automaticTransitionFromOpenToHalfOpenEnabled: true
management:
endpoints:
web:
exposure:
include: "*"
π§ͺ Test the Circuit Breaker
Send multiple requests to /api/products/123 and observe the fallback behavior after simulated failures. You can test using curl or Postman.
π Adding Retry (Optional)
resilience4j:
retry:
instances:
productServiceCB:
maxAttempts: 3
waitDuration: 500ms
@Retry(name = "productServiceCB", fallbackMethod = "fallbackForProduct")
π Monitoring with Actuator and Health Checks
Add the following dependency:
org.springframework.boot
spring-boot-starter-actuator
Visit
http://localhost:8080/actuator/health
http://localhost:8080/actuator/circuitbreakerevents
π¦ Sample Response
Fallback: Product service is currently unavailable. Please try later.
π§ Key Takeaways
- Circuit Breaker prevents resource exhaustion and cascading failures.
- Resilience4j offers simple annotations to integrate robust fault tolerance.
- Use fallback methods to provide better UX during downtimes.
- Combine CircuitBreaker with Retry and RateLimiter for resilient APIs.
π Conclusion
Using Resilience4j Circuit Breaker in Spring Boot enhances the resilience and stability of your microservices. It’s lightweight, easy to configure, and designed for Java functional programming.
β Donβt forget to monitor your breakers and fine-tune thresholds as your system evolves.