Circuit Breaker and Resilience with Resilience4j

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
Resilience4j Circuit Breaker Spring Boot

🧩 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:

  1. Closed: Requests flow normally.
  2. Open: All requests are blocked immediately.
  3. 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.