Microservices architecture allows a large application to be separated into a collection of loosely-coupled parts known as services, with each part having its distinct responsibility. A service often calls on another service in other to compose a response for a user request, and there is always a possibility that the other service being called is unavailable or fails to respond due to some internal errors which will result in the failure of both services. In other to avert such situations we use a Circuit Breaker.
What is Circuit Breaker?
You may probably be familiar with a circuit breaker as an automatic device for stopping the flow of current in an electric circuit as a safety measure. In a microservices architecture, the Circuit Breaker design pattern is used to prevent calls to microservice and sends a pre-defined response back in the case where a service is not working or fails to respond.
A circuit breaker keeps track of the responses by wrapping the call to the remote service and by keeping track of the results of the previous requests made to the remote service it can determine if the next request will fail. Preventing calls to the remote service when it is likely to fail guards against unnecessarily wasting critical resources and can give the server some spare time to recover. Let’s take an instance we have two services, Order service, and Catalogue service and the order service calls the service for catalogues but when the catalogue service fails to respond, the corresponding API for order service also fails but with the use of a circuit breaker such situation can be properly managed. consider the image below
The Circuit Breaker design pattern has 3 states.
Close: A circuit breaker is in a “closed” state when all operations function as expected and calls to a remote service responds successfully.
Open: When calls to a remote service return an error or fail to respond an internal counter is incremented and when it exceeds a predetermined limit the circuit breaker moves to an "open" state without any attempt to execute the real operation.
Half-Open: After a period of preconfigured time, the circuit breaker moves into the “half-open” state. Here the circuit breaker will allow a limited number of calls to pass through and if the requests succeed, the circuit breaker returns to the “closed” state, and operations resume as normal but If this request fails, the circuit breaker returns to the open state.
Types of Circuit Breaker
There are 2 types of circuit breaker patterns, Count-based and Time-based.
- Count-based: A count-based circuit breaker switches from a closed state to an open state when the last N requests have failed or timeout.
- Time-based: A time-based circuit breaker switches from a closed state to an open state when the last N seconds failed or timeout.
Using any of the types of circuit breakers, we can determine the criteria for failure or timeout. For instance, we can specify the count-based circuit breaker will trip and go to the Open State when 50% of the last 20 requests took more than 2s to complete, or for a time-based, we can specify that 50% of the last 60 seconds of requests took more than 5s.
What is Resilience4J?
According to the official release documentation, Resilience4J is a lightweight fault tolerance library inspired by Netflix Hystrix but designed for functional programming. Resilience4j provides higher-order functions (decorators) to enhance any functional interface, lambda expression, or method reference with a Circuit Breaker, Rate Limiter, Retry, or Bulkhead. You can stack more than one decorator on any functional interface, lambda expression, or method reference. The advantage is that you have the choice to select the decorators you need and nothing else.
For a detailed implementation of Circuit Breaker on Spring Boot using Resilience4J one of the libraries for implementing Circuit Breaker features check out this GitHub repository.
Also, check out this YouTube.