In microservice architecture, failures are inevitable. One failing service should not bring down the entire system. That’s where Resilience4j comes in — a lightweight fault tolerance library for Java.
🧠 Why Resilience?
- Protects your app from cascading failures
- Improves fault tolerance with:
- Circuit Breaker
- Retry
- Rate Limiter
- Bulkhead
- Time Limiter
- Fallbacks
🔧 1. Add Resilience4j Dependencies
👉 pom.xml
<dependency>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-spring-boot3</artifactId>
</dependency>
<dependency>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-micrometer</artifactId>
</dependency>
<dependency>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-all</artifactId>
</dependency>
🔌 2. Enable Resilience4j Circuit Breaker in a REST Client
Sample REST client with fallback
@RestController
@RequestMapping("/api/products")
public class ProductController {
@Autowired
private ProductService productService;
@GetMapping
@CircuitBreaker(name = "productService", fallbackMethod = "fallbackForGetProducts")
public ResponseEntity<List<String>> getProducts() {
return ResponseEntity.ok(productService.fetchProductList());
}
public ResponseEntity<List<String>> fallbackForGetProducts(Throwable ex) {
return ResponseEntity.ok(List.of("DEFAULT_PRODUCT_1", "DEFAULT_PRODUCT_2"));
}
}
Explanation:
@CircuitBreaker
watches the method.- If failures exceed the threshold, it opens the circuit.
- Fallback method is triggered when the service is down.
⚙️ 3. Configure Circuit Breaker (application.yml)
resilience4j:
circuitbreaker:
instances:
productService:
registerHealthIndicator: true
slidingWindowSize: 5
minimumNumberOfCalls: 5
failureRateThreshold: 50
waitDurationInOpenState: 10s
permittedNumberOfCallsInHalfOpenState: 2
automaticTransitionFromOpenToHalfOpenEnabled: true
Description of config:
Property | Meaning |
---|---|
slidingWindowSize | No. of recent calls to consider |
failureRateThreshold | % failure to open circuit |
waitDurationInOpenState | Wait time before trying again |
permittedNumberOfCallsInHalfOpenState | No. of test calls allowed |
automaticTransitionFromOpenToHalfOpenEnabled | Auto reattempt after open |
🔁 4. Add Retry Mechanism
@GetMapping("/retry")
@Retry(name = "productRetry", fallbackMethod = "retryFallback")
public String retryExample() {
if (new Random().nextBoolean()) {
throw new RuntimeException("Simulated failure");
}
return "Success after retry";
}
public String retryFallback(Exception ex) {
return "Fallback after retries";
}
Configuration:
resilience4j:
retry:
instances:
productRetry:
maxAttempts: 3
waitDuration: 2s
🧱 5. Rate Limiter
@GetMapping("/limited")
@RateLimiter(name = "productRateLimiter")
public String rateLimiterExample() {
return "Allowed";
}
Config:
resilience4j:
ratelimiter:
instances:
productRateLimiter:
limitForPeriod: 5
limitRefreshPeriod: 1s
This allows 5 calls per second.
🧊 6. Bulkhead (Concurrency Control)
@GetMapping("/bulkhead")
@Bulkhead(name = "productBulkhead", type = Bulkhead.Type.THREADPOOL)
public String bulkheadExample() {
return "Access granted";
}
Config:
resilience4j:
bulkhead:
instances:
productBulkhead:
maxConcurrentCalls: 3
maxWaitDuration: 1s
Restricts the number of concurrent requests.
📊 7. Monitoring with Actuator & Micrometer
Add Actuator and Micrometer
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
application.yml
management:
endpoints:
web:
exposure:
include: "*"
endpoint:
health:
show-details: always
Metrics available at /actuator/metrics
Prometheus and Grafana can be added for visualization
🔄 8. Summary
Feature | Annotation | Use Case |
---|---|---|
Circuit Breaker | @CircuitBreaker | Fail fast when service is down |
Retry | @Retry | Retry failed calls |
Rate Limiter | @RateLimiter | Throttle excessive requests |
Bulkhead | @Bulkhead | Limit concurrent executions |
Time Limiter | @TimeLimiter | Timeout protection |
🛠 Tools It Integrates With
- Spring Boot Actuator
- Micrometer (for monitoring)
- Prometheus & Grafana
- Spring Cloud Gateway (for filtering + retry)
- Spring Retry (alternate retry mechanism)
✅ Next Up: Part 22 – Spring Boot and Kafka Messaging for Event-Driven Architecture