DEV Community

Cover image for Basics of Resilience4j with spring boot
Rajendra🙏🏼👇🏽
Rajendra🙏🏼👇🏽

Posted on

Basics of Resilience4j with spring boot

What is a Circuit Breaker pattern?

The circuit breaker pattern is something that can prevent from repeatedly trying to call a service or a function that will likely fail and save CPU cycles.

It is pretty common for a software service to call remote software service and the remote service can fail or not respond as expected and this is pretty common in a microservice architecture when you have hundreds of clients calling the service which is failing eventually all the resources get used up, that is why it is a best practice to implement circuit breaker pattern in those scenarios.

How does Circuit Breaker work?

Circuit Breaker has three states Closed State, Open State, Half Open State. The image below shows how the flow from one state to another changes. The Circuit Breaker will be in the Closed state when everything is running as expected when failure starts coming it waits until the set threshold limit is reached then goes to Open state. While in Open states no calls will be going to failing remote service until certain wait time, then it goes to Half-Open state, in this stage reduced amount of calls goes to remote service to make sure the calls are successful, IF the calls are responding as expected it will go to Closed state or it goes back to Open state avoiding calls to failing remote service.

Circuit Breaker Pattern

What is Resilience4j?

Resilience4j is a lightweight, easy-to-use fault tolerance library designed for Java 8 and functional programming, it is a lightweight as it doesn't depend on any other external libraries.

If you are a video person here is the video tutorial

Please show some love and subscribe to my channel Subscribe Hacker Heap.

Implementation with Spring boot2

Add the dependency to pom.xml

<dependency>
            <groupId>io.github.resilience4j</groupId>
            <artifactId>resilience4j-spring- 
                            boot2</artifactId>
            <version>1.3.1</version>
</dependency>

Add the required configurations to application.yml file or application.properties file

resilience4j:
  circuitbreaker:
    configs:
      default:
        registerHealthIndicator: true
        slidingWindowSize: 10
        minimumNumberOfCalls: 5
        permittedNumberOfCallsInHalfOpenState: 3
        automaticTransitionFromOpenToHalfOpenEnabled: true
        waitDurationInOpenState: 5s
        failureRateThreshold: 50
        eventConsumerBufferSize: 10
        recordExceptions:
                - org.springframework.web.client.HttpServerErrorException
                - java.util.concurrent.TimeoutException
                - java.io.IOException
    instances:
      mainService:
        baseConfig: default

The above is the base configuration for resilience4j, waitDurationInOpenState is how much time the circuit breaker will be in Open state before it goes to Half-Open state .
failureRateThreshold sets the threshold limit before it goes to the open state.
recordExceptions records the type of exception on which you want your circuit breaker to be activated.
You can have multiple profiles for different service calls or operations, the above configuration has just one profile default, which is assigned to the mainService declared in the below class.

package com.springsleuth.demo.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import io.github.resilience4j.circuitbreaker.annotation.CircuitBreaker;

@RestController
public class MainServiceController {

    private static final Logger LOGGER = LoggerFactory.getLogger(MainServiceController.class);

    private static final String MAIN_SERVICE = "mainService";

    @Autowired
    private RestTemplate restTemplate;

    @Bean
    public RestTemplate getRestTemplate() {
        return new RestTemplate();
    }


    @GetMapping("/getSleuthTest")
    @ResponseStatus(HttpStatus.OK)
    @CircuitBreaker(name = MAIN_SERVICE, fallbackMethod="testFallBack")
    public ResponseEntity<String> getSleuthTest(){
        LOGGER.info("I'm here in main service calling service one");
        String response = restTemplate.getForObject("http://localhost:8081/serviceOne", String.class);
        return new ResponseEntity<String>(response, HttpStatus.OK);

    }


    private  ResponseEntity<String> testFallBack(Exception e){
        return new ResponseEntity<String>("In fallback method", HttpStatus.INTERNAL_SERVER_ERROR);
    }

}

In the above class, we activated circuit breaker using @CircuitBreaker annotations, it has two parameters.
1) service name, which is the service name defined in the config file (mainService) with default profile.
2) fallBackMethod, which is called when an error occurs, fallBackMethod is optional.

Top comments (4)

Collapse
 
dinakar profile image
Dinakar

Thanks for the write up.
Incase of application.properties , how do I need to specify this:

recordExceptions:
- org.springframework.web.client.HttpServerErrorException
- java.util.concurrent.TimeoutException
- java.io.IOException

Collapse
 
dhanaryali profile image
Dhanaraju Ryali

In Resilience4j Circuit Breaker, do we have any configuration to retry particular number of times when the circuit is OPEN? or we need to use Retry configuration to achieve the same?

Collapse
 
mateuszjarzyna profile image
Mateusz Jarzyna

Are you the author of this lib?

Collapse
 
nagarajendra profile image
Rajendra🙏🏼👇🏽

No I’m not