Circuit Breaker Pattern in Microservices (Spring BOOT + Resilience4j)
- 4.4/5
- 4341
- Jul 20, 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