The Circuit Breaker pattern is a microservices design pattern that is used to protect the microservices architecture from cascading failures to enhance the resiliency and fault tolerance in a distributed system.
What is Cascading Failure?
Cascading failure is a type of failure in which one part of the system fails; it leads to failure of other parts of the system. Say, if we have 3 services m1, m2, and m3, and m1 is calling to m2, m2 calls to m3, and now, due to some reason, m3 fails, it will lead to failure of m2, and so as m1, this is called cascading failure.
Why do we need Circuit Breaker Pattern in Microservices?
In the below picture, we see three services m1, m2, and m3 working in a microservices architecture. Let’s assume, for some reason, the m2 service is down and the m1 service will receive some error, say 500-Internal Server Error. In this scenario, if m1 service keeps calling m2 service, then it is just a waste of resources.
As the m1 service keeps calling the m2 service, it will lead to resource wastage and nothing else. One naive solution could be that we can handle the error using the try-catch block at m2 service and send the error response to the m1 service to stop calling.
But this is not an appropriate solution, as in microservices architecture, intermittent failures are common, and we cannot predict for how long the M2 service will be down. This is why; we should not stop allowing the request calls from m1 to m2 services.
We can resolve above issue as following:
- We should allow all the requests from m1 service to m2 service, and instead of processing all the requests, we should set some threshold.
- By setting some threshold, what we meant is that we will wait for a few more requests, and if the failure rate exceeds the threshold, then we will stop allowing the request to call microservices.
What is Circuit Breaker Pattern in Microservices?
As the name suggests, the Circuit Breaker Pattern is analogous to an electrical circuit. It prevents the system from repeatedly trying to execute an action that is likely to fail, protecting resources from overload. The Circuit Breaker pattern operates in three states:
- Closed
- Open
- Half Open
By default, the Circuit Breaker pattern is in a Closed state, which means everything is functioning normally and requests are allowed to flow through.
If we have setup a threshold of 50%, that means if the 50% of requests from one to another service (say, m1 to m2 service) fails, then immediately a trip in the circuit will occur and the status will be changed from Closed to Open.
In the above picture, we see that more than 50% of the requests failed, which means the threshold is reached and the application status will be changed from Closed to Open and does not allow to call the dependent microservices.
As the state of microservice architecture changed from closed to open, in Open state, we need to have some timeout (say, 5 seconds). i.e., as 5 seconds get expired, the application state will automatically change from open to half open.
In Half Open, it allows few requests for m2 service and checks for the application availability. If again 50% of requests failed, again the application moved from half open to open state, and if it passes that means the threshold has not been reached, the application will move from half open to closed state.