Skip to main content

Circuit Breaker Pattern in Microservices (Spring BOOT + Resilience4j)

Read Also: Spring Cloud Circuit Breaker + Resilience4j

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


Comments

Popular posts from this blog

Deploying Spring Boot microservices on Kubernetes Cluster

This article guides you through the deployment of two Spring Boot microservices, namely "order-service" and "inventory-service," on Kubernetes using "MiniKube" . We will establish communication between them, with "order-service" making calls to an endpoint in "inventory-service." Additionally, we will configure "order-service" to be accessible from the local machine's browser . 1) Create Spring Boot microservices The Spring Boot microservices, "order-service" and "inventory-service," have been developed and can be found in this GitHub repository. If you are interested in learning more about creating Spring Boot REST microservices, please refer to this or this (Reactive) link. 2) Build Docker Images The Docker images for both "order-service" and "inventory-service" have already been generated and deployed on DockerHub, as shown below. codeburps/order-service cod...

Circuit Breaker Pattern with Resilience4J in a Spring Boot Application

Read Also: Spring Cloud Circuit Breaker + Resilience4j Resilience4j is a lightweight fault tolerance library that draws inspiration from Netflix Hystrix but is specifically crafted for functional programming. The library offers higher-order functions, known as decorators , designed to augment any functional interface, lambda expression, or method reference with features such as Circuit Breaker, Rate Limiter, Retry, or Bulkhead . These functionalities can be seamlessly integrated within a project, class, or even applied to a single method. It's possible to layer multiple decorators on any functional interface, lambda expression, or method reference, allowing for versatile and customizable fault tolerance. While numerous annotation-based implementations exist online, this article focuses solely on the reactive approach using router predicates and router functions . How Circuit Breaker Pattern works? In general, a circuit breaker functions as an automatic electrical s...

How to create a basic Spring 6 project using Maven

Below is a step-by-step guide to creating a basic Spring project using Maven. 1) Create a Maven Project Use the following Maven command to create a new Maven project. mvn archetype:generate -DgroupId=com.tb -DartifactId=spring-demo -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false 2) Import in IntelliJ IDEA If you haven't already, open IntelliJ IDEA on your system. Go to "File" > "New" > "Project from Existing Sources..." . In the file dialog, navigate to the directory where your Maven project is located. Select the pom.xml file within the project directory and click "Open." 3) Update pom.xml In total, the application requires the below-mentioned dependencies: 4) Create Spring Configuration Create a Java configuration class that uses annotations to define your Spring beans and their dependencies. This class should be annotated with @Configuration . 5) Create the Main Application C...