Circuit breakers are a design pattern to create resilient microservices by limiting the impact of service failures and latencies. In this blog, we demonstrate how to incorporate a circuit breaker into microservices to ensure that a system remains responsive and available even in the event of failures or unexpected loads.
Before we talk about Circuit breakers', let’s briefly look at microservice architecture and in which scenario it is frequently used.
What is Microservice Architecture?
In the microservice architecture, web applications are developed by dividing their functionality into separate, autonomous services that work together to deliver seamless and responsive performance. These services are developed and deployed individually and are loosely coupled, in contrast to the interdependent components of a monolithic application.
Let's take the example of “Spotify”. It requires many different services, so each service deals with a specific task. For example, a search engine, user behavioral analytics for a recommendation engine, autogenerated playlists, content tagging, and so on. So each of the services is built separately and communicates with each other.
Learn more about Microservice architecture here
What is the circuit breaker pattern?
The circuit breaker pattern is used to prevent downstream failures in distributed systems. This design pattern has been extensively used to address the problem of downstream failures.
It helps prevent a cascading failure across a distributed system, by allowing a microservice to temporarily "trip" its circuit and enter a fallback state when it starts to experience issues. This fallback state could be to stop serving requests, to serve a default or cached response, or to redirect requests to a different instance of the service. Circuit breakers are used to protect the overall system from overloading or failing due to a single service that is experiencing issues. They can help to improve the resilience and stability of a microservices architecture.
A circuit breaker can be in one of the following states:
Circuit Breakers vs. Timeouts for Microservices
We now know what the purpose of a circuit breaker is. Timeouts can be used in the same way to accomplish the same purpose for cascading services. Microservices use timeouts to limit the amount of time they will wait for a response from downstream services. If the downstream service does not respond within the specified timeout period, the microservice will terminate the request and return an error to the caller. Timeouts are typically used to protect a microservice from getting stuck waiting for a response from a downstream service that is taking too long to respond.
In summary, circuit breakers are used to protect a microservice from making requests to a downstream service that is failing, while timeouts are used to protect a microservice from getting stuck waiting for a response from a downstream service. Both mechanisms can be used to improve the reliability and resiliency of a microservice architecture.
The 5 Benefits of Using Circuit Breakers
The purpose and concept of circuit breakers are now clear to us, so let's put them into practice.
We will be using “Golang” and the "gobreaker" (https://github.com/sony/gobreaker) package to implement a circuit breaker in Go, which provides a simple and easy-to-use implementation of the circuit breaker pattern.
Initialize the new circuit breaker with a timeout and a threshold of 5 failures. After 5 failures circuit breaker will block all requests unless it gets successful requests. If we get five unsuccessful attempts, it will trip the circuit breaker and change the state to open.
We need to write the GetData function, which will hit the API with the circuit breaker object.
And finally, the main function is to call the APIs. We have one correct URL and another incorrect URL for the sake of tripping the circuit breaker. We'll call the API 10 times, and when the counter reaches 5, we'll use the correct API.
O/P :
As we can see, the first four attempts are made, and on the fifth attempt, the circuit state is changed from closed to open. And then circuit breaker will then retry to fulfill the request, and if successful, it will mark the request as "open" to "half-open" and “half-open” to "open," and once we have enough successful requests, it will mark “half-open” to "closed."
Conclusion:
The circuit-breaker pattern can aid in the reliability of microservice architectures. It avoids making unnecessary calls to underlying services when they are unavailable, which improves overall system stability. Incorporating a circuit breaker into your microservices can help to ensure that your system remains responsive and available even in the event of failures or unexpected loads.