Home Post Microservices

Circuit Breaker Pattern in Microservices (Spring BOOT + Resilience4j)

Mar 31, 2024

In this article, we will learn how to use Resilience4j with Spring Cloud to make our Spring BOOT microservices more resilient and auto-recoverable.

A circuit breaker is used to minimize the damage that a slow or unresponsive downstream microservice can cause in a large-scale system of synchronously communicating microservices.

How does a circuit breaker function?

If a circuit breaker detects too many errors, it will "open" its circuit and not allow new calls.

When the circuit is "open," it doesn't wait for a new error to happen on subsequent calls. Instead, it directly redirects the call to a fallback method.

A fallback method can return a response from a "cache" or simply return an error message.

After a configurable time, the circuit breaker will be "half-open", allowing a configurable number of calls to see whether the issue that caused the failures is gone.

If new failures are detected by the circuit breaker, it will "open" the circuit again and go back to the fail-fast logic. Otherwise, it will close the circuit and go back to normal state.

Spring Cloud Circuit Breaker

Spring Cloud Circuit Breaker provides an abstraction layer for circuit breakers, and "Resilience4j" can be configured to be used under the hood.

Implementation

We will apply the circuit breaker in calls from the "order-service" to the "catalog-service".

% mkdir spring-boot-circuit-breaker
% cd spring-boot-circuit-breaker

1) The "order-service"

 

Let's bootstrap a new Spring Boot project with the help of the Spring Boot CLI command-line tool.

The Spring Boot CLI is a command line tool that you can use to bootstrap a new project from start.spring.io or encode a password.

One of the easiest ways to set up Spring Boot CLI is to use SDKMAN.

% sdk install springboot
spring init \
--boot-version=2.7.7 \
--build=maven \
--java-version=17 \
--packaging=jar \
--name=order-service \
--package-name=com.codeburps \
--groupId=com.codeburps \
--dependencies=actuator,web,lombok \
--version=1.0.0-SNAPSHOT \
order-service

To use Swagger UI, we need to add an additional Maven dependency:

<dependency>
    <groupId>org.springdoc</groupId>
    <artifactId>springdoc-openapi-ui</artifactId>
    <version>1.6.14</version>
</dependency>
1.1) Add Resilience4j dependency

To use Resilience4j, we need to add an additional Maven dependency:

<dependency>
    <groupId>io.github.resilience4j</groupId>
    <artifactId>resilience4j-spring-boot2</artifactId>
    <version>2.0.2</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>
1.2) Add Configuration

Resilience4j can be configured using standard Spring Boot configuration files.

1.3) Code Changes

The circuit breaker can be applied by annotating the method it is expected to protect with @CircuitBreaker(), which in this case is the getProduct() method in the ProductClientImpl class.

When the circuit breaker is open, it will not permit calls to the getProduct() method; instead, it will immediately throw a CallNotPermittedException exception.

The "fallbackMethod" must follow the signature of the method the circuit breaker is applied for and also have an extra last argument used for passing the exception that triggered the circuit breaker.

Source code: GitHub

2) The "catalog-service"

Let's bootstrap a new Spring Boot project with the help of the Spring Boot CLI command-line tool.

spring init \
--boot-version=2.7.7 \
--build=maven \
--java-version=17 \
--packaging=jar \
--name=catalog-service \
--package-name=com.codeburps \
--groupId=com.codeburps \
--dependencies=actuator,web,lombok \
--version=1.0.0-SNAPSHOT \
catalog-service

We can build this microservice with the following command:

% cd catalog-service
% mvn clean install

We are applying the circuit breaker in calls from the "order-service" to the "catalog-service".

The "catalog-service" is a simple Spring BOOT service, no extra code or "Resilience4j" related changes are needed in this service.  

Source code: GitHub

Monitoring

Resilience4j exposes the current state of a circuit breaker using the microservices' actuator health endpoint, /actuator/health.

The circuit breaker also publishes events on an actuator endpoint, for example, state transitions, /actuator/circuitbreakerevents.

Circuit breakers can also use Spring Boot's metrics system to publish metrics to monitoring tools like Prometheus.

Source code: GitHub

avatar

NK Chauhan

NK Chauhan is a Principal Software Engineer with one of the biggest E Commerce company in the World.

Chauhan has around 12 Yrs of experience with a focus on JVM based technologies and Big Data.

His hobbies include playing Cricket, Video Games and hanging with friends.

Categories
Spring Framework
Microservices
BigData
Core Java
Java Concurrency