DEV Community

Cover image for Understanding Circuit Breaker Pattern in Spring Boot for Resilient Microservices
Tharindu Dulshan Fernando
Tharindu Dulshan Fernando

Posted on

Understanding Circuit Breaker Pattern in Spring Boot for Resilient Microservices

As multiple independent services interact with one another in a microservices design, maintaining system resilience becomes important. Managing failures that could arise from a service outage or high latency is one typical problem. A design pattern called the circuit breaker pattern solves this problem by offering a fallback and preventing a cascading failure. In this blog, we’ll look at the Circuit Breaker pattern of Spring Boot apps.

Understanding the Circuit Breaker Pattern:

An electrical circuit breaker and the circuit breaker pattern play a similar role. It keeps an eye out for malfunctions and, when reaching a predetermined threshold, opens the circuit to stop more calls to the malfunctioning service. This enables the system to fail gracefully and restart when the malfunctioning service is back up and running.

Spring Boot Implementation:

Maven

<!-- Add Resilience4j dependency in pom.xml -->
<dependency>
    <groupId>io.github.resilience4j</groupId>
    <artifactId>resilience4j-spring-boot2</artifactId>
</dependency>
Enter fullscreen mode Exit fullscreen mode

Gradle

<!-- Add Resilience4j dependency in build.gradle -->
dependencies {
    implementation 'io.github.resilience4j:resilience4j-spring-boot2:1.7.1'
}
Enter fullscreen mode Exit fullscreen mode

Let’s now build a basic Spring Boot application that breaks circuits using Resilience4j.

1. Create a Spring Boot Application:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class CircuitBreakerTestApplication {

    public static void main(String[] args) {
        SpringApplication.run(CircuitBreakerTestApplication.class, args);
    }
}
Enter fullscreen mode Exit fullscreen mode

2. Create a Service with Circuit Breaker:

Create and name the service class as TestService, which will have a method that we want to protect with a circuit breaker:

import org.springframework.stereotype.Service;
import io.github.resilience4j.circuitbreaker.annotation.CircuitBreaker;

@Service
public class TestService {

    @CircuitBreaker(name = "testService", fallbackMethod = "fallbackMethod")
    public String invokeExternalService() {
        // Here you can simulate a call to an external service
        // In a real-world scenario, this could be an HTTP call, database query, etc.
        if (Math.random() > 0.5) {
            throw new RuntimeException("Service failure");
        }
        return "External service response";
    }

    public String fallbackMethod(Exception e) {
        return "Fallback response";
    }
}
Enter fullscreen mode Exit fullscreen mode

In the CircuitBreaker annotation, name is the identifier for the circuit breaker, and fallbackMethod is the method that is to be called when the circuit is open.

3. Write a controller class to Invoke the TestService:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestController {

    @Autowired
    private TestService testService;

    @GetMapping("/invokeService")
    public String invokeService() {
        return testService.invokeExternalService();
    }
}
Enter fullscreen mode Exit fullscreen mode

4. Enable Resilience4j Configuration

You can add the below properties to your application.properties or application.yml file to configure Resilience4j:

resilience4j.circuitbreaker.configs.default.failureRateThreshold=50
resilience4j.circuitbreaker.configs.default.slidingWindowSize=5
Enter fullscreen mode Exit fullscreen mode

5: Monitor Circuit Breaker State (Not a must)

In order to monitor the state of the circuit breaker, you can also add the following dependencies for Micrometer and Prometheus:

Maven:

<dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
Enter fullscreen mode Exit fullscreen mode

Gradle:

implementation 'io.micrometer:micrometer-registry-prometheus'

Enter fullscreen mode Exit fullscreen mode

Now Resilience4j Circuit Breaker dashboard can be accessed at http://localhost:8080/actuator/circuitbreakers.

6: Test Circuit Breaker

Utilize the /api/invokeService endpoint to submit requests while running your Spring Boot application. Change the Math.random() condition in the callExternalService method to simulate failures.

Observe how the state of the circuit breaker dashboard varies according to the success or failure of service calls.

Conclusion

The above example shows how to set up Resilience4j’s Circuit Breaker in a Spring Boot application in a basic manner. Depending on your unique use case and the interactions with external services, adjustments can be made as required.

References

https://spring.io/projects/spring-cloud-circuitbreaker

https://www.baeldung.com/spring-cloud-circuit-breaker

Github

https://github.com/tharindu1998/springboot-circuitbraker-example

Top comments (0)