This content originally appeared on Level Up Coding - Medium and was authored by daleef rahman
A Stitch In Time Saves Nine
Covid 19 pandemic caused a lot of countries to impose lockdowns in an attempt to contain the disease. Only essential services were kept open for access to the public. Most of us had to stay at home for weeks and months.
It disrupted normal life harder than ever. But why did governments take such a drastic step?
This measure was inevitable to prevent large-scale outbreaks, which would have been devastating otherwise. Eventually, the lockdown was lifted in phases, as covid cases declined.
The whole scenario is a real-life analogy of a circuit breaker.
The concept of circuit breakers originally comes from electronics. If you check Wikipedia, it is defined as an automatic switch to protect a circuit from damage caused by an overcurrent or short circuit. It’s an automatic means of cutting off power from a faulty system.
As soon as the fault condition is corrected, the switch is closed to restore power to the interrupted circuit.
So, how does this apply to us?
Why do we need a circuit breaker in our microservices?
Let’s face it, all services can fail or falter at some point in time. Networks can become flaky, systems might starve on resources, databases might go down, stop the world GCs can kick in, or zombies might attack the data center. Okay, may not be the last one 😁. But you get the point!
We need to bake in fault tolerance in our services to handle these situations gracefully.
Consider this example.
From the API server, we are calling the movie recommendation service to give movie recommendations to the users. Suppose the Movies DB is slow due to some reason, and consequently, the Movie recommendation service is also slow. What will happen if we keep on sending requests from the API server? It will add more pressure on the Db and could further worsen the situation.
Moreover, movie recommendation service’s threads will be busy processing high response requests which will lead to a decrease in the number of free threads to process other requests which eventually will lead to an outage of the service.
Rather than keep on sending requests and overburden the movie recommendation service, we can rather take a more intelligent route. API server can tell the recommendation service: “Hey why don’t you take a break? Take some rest and recover from whatever problems you have. I will check with you after some time”.
We can give API server a switch to turn off and stop all the communications to the movie recommendations service for some time.
What will API server do with the requests that are supposed to be sent to the recommendation service? Well, it has 2 options. If the faulty service is a critical service, then it can fail fast and show an error message to the users. If the service is a non-critical one, then we can bypass it and provide a slightly degraded experience to users.
Afterwards, we can retry a few requests to check if the faulty service is still unavailable or slow.
Here’s a video showing how Hotstar does graceful degradation by bypassing non-critical services when there is an unexpected fault.
If we implement this solution ourselves, it will be intrusive to the codebase and will add significant overhead. This is where a circuit breaker can help us.
What you want the circuit breakers to do is:
- Watch for service faults in real-time. Look for excessive faults, unreasonably slow response time, etc.
- Shut down and interrupt that flow to prevent overloading the rest of the system.
- Check periodically to see if the faulty service has recovered.
Implementing circuit breaker in spring boot with Resiliency4j
Hysterix, Resiliency4j and Sentinel are some of the most popular circuit breaker libraries. Hysterix is currently deprecated and is in maintenance mode. Compared to Sentinel, Resilience4j is very lightweight and has more granularity of controls. In this demo, we will use Resilience4j.
Our demo will use a spring-boot based movie dashboard service that recommends movies to users. The dashboard service talks to the movie recommendations service via a Eureka server.
First, let’s set up the movie recommendation service that returns recommended movies for a user.
We now configure the movie dashboard service that will be our front-end to the movie recommendation service.
The complete code can be found here.
Now run the services and the eureka server. We can now access the /dashboard endpoint on our movie dashboard service port, and see our movies recommendations list.
We have our services ready. Put on your work boots and get ready for the circuit breaker!
First, we need to add the reactive version of the Resilience4j circuit breaker as a dependency.
Once we have our circuit breaker, all we have to do is call run. Run takes a Mono or Flux and an optional Function. The optional Function parameter acts as our fallback if anything goes wrong with the original request. In our example here we will fall back to getDefaultMovies().
That’s it. Our circuit breaker is ready.
Now let’s shut down the movie recommendations service. Our source service is gone, but thanks to Resilience4J, we can fall back to default movies and keep our users happy.
Resiliency4j configurations
Resiliency4j provides a lot of granular configurations to change the default behavior of the circuit breaker.
- You can choose between a count-based sliding window and a time-based sliding window. For example, we can configure a count-based circuit breaker to “open the circuit” if 70% of the last 25 calls failed. Similarly, we could tell a time-based circuit breaker to open the circuit if 80% of the calls in the last 30s failed.
- You can configure a threshold for the failure rate, above which the circuit breaker transitions to open and starts short-circuiting calls.
- You can configure the duration threshold above which calls are considered as slow and increase the rate of slow calls.
- You can define a list of exceptions that should count as a failure.
Find the full list of configurations here.
Parting thoughts
I hope this article was able to clarify why circuit breakers are important in creating fault-tolerant systems and how to implement one.
Circuit breakers are only one piece of the puzzle to building fault tolerance for your system. Additionally, there are several other fault tolerance mechanisms that Resiliency4J provides, such as bulkheads, ratelimiters, retries, and time limits. But that’s topic for another blog!
Circuit breaker pattern simplified. Why do you need one in your microservice? was originally published in Level Up Coding on Medium, where people are continuing the conversation by highlighting and responding to this story.
This content originally appeared on Level Up Coding - Medium and was authored by daleef rahman
daleef rahman | Sciencx (2022-05-10T12:08:55+00:00) Circuit breaker pattern simplified. Why do you need one in your microservice?. Retrieved from https://www.scien.cx/2022/05/10/circuit-breaker-pattern-simplified-why-do-you-need-one-in-your-microservice/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.