A Discussion on Circuit Breaks in the Microservices Architecture: HttpClient Implementation

Eric Barroca
The Startup
Published in
4 min readJan 30, 2021

This article is part of a series on Circuit Breaks, below you can find a list on all of them.

Previously, on A Discussion on Circuit Breaks in the Microservices Architecture, we briefly talked about what are Circuit Breaks, how they work and why it can be a good tool in the Microservices Architecture.

A summary of a Circuit Break State Machine is shown in the picture below for revision.

Circuit Break Flow — Adapted from [1]

In this continuation we will talk about how to implement Circuit Breaks as an “envelope” for your Http Clients. Furthermore, it is presented an analysis on this implementation benefits and challenges.

**For this article tasks I am using .net core and the Polly package.

Creating HttpClients through HttpClientFactory with Polly Circuit Break policies.

Polly is a transient-fault-handling library for developers that want to implement policies on their applications [2]. It allows developers to implement these policies as actions through extensions methods with strict rules definitions for Retry, Fallback, Circuit Break and other type of policies [2,3].

For our exercise we will create a Circuit Break Policy that will execute at every request for the HttpClient that it is attached. If, for this client, two requests throw an exception the circuit will break (thus, be opened) and will stay this way for 1 minute. If another request is made during this 1 minute interval it will fail automatically, without trying to reach the endpoint specified by the request (since the circuit is open). After this interval has passed our application will be able to try connecting to the request url again, and if the request does not fail, then the CB will move back to the closed state.

So, how do we create a Circuit Break Policy?

Circuit Break Policy Implementation

The code above answers that question for us. It is an extension method to create and attach a Circuit Break Policy to a HttpClient. First it specifies what your policy handles (lines 16–17), which in this case is any type of exception (but it could be a specific response message, or other types) [2,3].

Then the CircuitBreakAsync method creates a Circuit Break Policy (no kidding, right?) [2,3]. Its first two parameters specify the amount of unsuccessful tries that can happen before the CB breaks (is opened), and the time the circuit remains in open state [2,3]. The other two parameters are the callbacks for when the circuit breaks, and when it closes again [2,3]. (lines 18–30).

For last the policy is attached to the HttpClient (done on line 33) [3].

PS: Both callbacks use a context object. This object is a Dictionary used to pass information from the request to these circuit break callbacks. In this case it is used to pass the Log Service (ILogger).

Now it is time to create a HttpClient through the HttpClientFactory and attach this CB Policy, as shown bellow on the Startup.cs file, making our policy execute every time our application makes a request using this HttpClient [3].

HttpClient Creation

Thus, the only thing that is missing is an example of how to use this HttpClient. This example is presented below.

Order Service

**The complete source code for this article can be found on: https://github.com/ericbarroca/circuitbreak.

Implementation Benefits and Challenges

The main advantage of this implementation is the segregation of concerns between clients, policies, and requests, maintaining the Circuit Break State Machine transparent to developers.

Enabling developers to envelop their HttpClient with policies enables them to not worry about managing these policies through dependency injection or other mechanisms in their different application services classes (not to be confused with microservices). This means that every time a developer calls a HttpClient defined on the HttpClientFactory it will always execute the policies attached to it.

Other benefit is the ability to use one and only one HttpClient to call all endpoints belonging to one microservice, which means that all the requests within this client obey the same policies.

However developers can create infinity clients with different polices. This possibility takes advantage of the separation of concerns and clustering methodologies, giving more flexibility (without increasing complexity) for the implementation of their application architecture with respect to CBs. Be it one CB by microservice or a CB per type of request.

Unfortunately, there is no implementation or architecture that is best for all kinds of situations. Think about this scenario:

Before an application makes a call to another microservice endpoint it has to do some calculations and other tasks that consume CPU, Memory and worst of all…takes TIME! With the current implementation presented in this article we would still impact our application performance unnecessarily. So how can we prevent this?

We will talk about that on the next article, using other implementation with the Polly library.

References

--

--

Eric Barroca
The Startup

Software Engineer since 2011, Master in Space Systems Engineering and currently working with AWS/Kubernetes and .Net Core to improve teams DevOps experience.