Implementing Circuit Breaker pattern using Resilience4J | Fault Tolerance | SpringBoot Microservices

Prashant KatarePrashant Katare
2 min read

We have a UserService microserviece which is makes call to other microservices and we would like to implement circuit breaker pattern here.

Step 1 → Add dependencies -

  • Spring Boot Actuator | OPS → To monitor the health of our microservice application.

  • Starter AOP → To be able to send matrics.

  • resilience4j-spring-boot3 (Check the one applicable to your SpringBoot and Java version)

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-aop -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
    <version>3.3.3</version>
</dependency>

<!-- https://mvnrepository.com/artifact/io.github.resilience4j/resilience4j-spring-boot3 -->
<dependency>
    <groupId>io.github.resilience4j</groupId>
    <artifactId>resilience4j-spring-boot3</artifactId>
    <version>2.2.0</version>
</dependency>

Step 3 → Add @CircuitBreaker to the controller method that makes call to other microservices. We will also give “name” and a “fallback“ method for this method.

@CircuitBreaker(name="RATING_HOTEL_BREAKER", fallbackMethod="ratingHotelFallback")
@GetMapping("{userId}")
public ResponseEntity<UserEntity> getUser (@PathVariable String userId){
    UserEntity tempUser = userService.getUser(userId);

    Rating [] ratings = ratingService.getAllRatings(userId);    
    List<Rating> allRatings = Arrays.stream(ratings).toList();

    tempUser.setRatings(allRatings);
    return ResponseEntity.ok(tempUser);
}

Step 4 → Implement the fallback method. The fallback method runs when the RatingService microservice is down and cannot send response. In such case after a certain number of attempts the circuit pattern will trip and the dummy response from the fallback method will be sent.

Fallback method must have the same return type and parameters as the original API method. Also fallback method must have a parameter of type Exception.

    public ResponseEntity<UserEntity> ratingHotelFallback (String userId, Exception ex){

        UserEntity user = UserEntity.builder()
                                .userId("12345")
                                .name("Dummy User")
                                .email("Dummy@dev.com")
                                .about("This is a dummy user.")
                                .build();

        System.out.println("Something went wrong : "+ex);

        return new ResponseEntity<>(user, HttpStatus.OK);
    }

Step 5 → Add configurations

  • Actuator configuration -

      management.health.circuitbreakers.enabled=true
      management.endpoints.web.exposure.include=health
      management.endpoint.health.show-details=always
    
  • resilience4j configuration - (“RATING_HOTEL_BREAKER“ in below configurations is the name we gave to the API method in Step 3.)

      resilience4j.circuitbreaker.instances.RATING_HOTEL_BREAKER.register-health-indicator=true
      resilience4j.circuitbreaker.instances.RATING_HOTEL_BREAKER.event-consumer-buffer-size=10
      resilience4j.circuitbreaker.instances.RATING_HOTEL_BREAKER.failure-rate-threshold=50
      resilience4j.circuitbreaker.instances.RATING_HOTEL_BREAKER.minimum-number-of-calls=5
      resilience4j.circuitbreaker.instances.RATING_HOTEL_BREAKER.automatic-transition-from-open-to-half-open-enabled=true
      resilience4j.circuitbreaker.instances.RATING_HOTEL_BREAKER.wait-duration-in-open-state=6s
      resilience4j.circuitbreaker.instances.RATING_HOTEL_BREAKER.permitted-number-of-calls-in-half-open-state=3
      resilience4j.circuitbreaker.instances.RATING_HOTEL_BREAKER.sliding-window-size=10
      resilience4j.circuitbreaker.instances.RATING_HOTEL_BREAKER.sliding-window-type=COUNT_BASED
    

Let’s test now. If our RatingService is down and we hit the UserService API to get user by userId, we get this dummy response from the fallback method we implemented -

We can check the Circuit Breaker details from the actuator health end point ( http://localhost:8081/actuator/health ) -

0
Subscribe to my newsletter

Read articles from Prashant Katare directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Prashant Katare
Prashant Katare

Experienced Spring Boot Developer with over 3+ years of expertise in developing scalable and high-performance web applications and microservices. Proficient in Java and Spring Boot frameworks, with hands- on experience in RESTful APIs and Microservices architecture. Adept at building secure, database-driven applications and integrating various third- party services. Strong problem-solving skills with a focus on delivering clean, maintainable, and efficient code.