The previous two blog entries were dedicated to illustrating how to use Ocelot and Polly for building Circuit Breaker. But what exactly is a circuit breaker? Let us dive into a bit of detail on the same.
If one was to observe microservices or any service-oriented architectures, it would not be hard to say that transient errors are not uncommon to them. The service could end up unserviceable temporarily for a variety of reasons. But the important part is, these are transient errors.
Circuit Breakers allows services to recover from transient errors, especially when a Retry Pattern falls short. In fact, the Retry pattern works when the recovery time is really short. But when the recovery time is slightly longer, Circuit Breakers seems to be more fit. The Circuit Breaker prohibits accessing an operation when it is likely to fail, at the same time, it allows the application to access the operation when the likelihood of success is higher or when the problem seems to have recovered by tracking recent failures and deciding whether to allow operation.
Doesn’t that sound like Retry Pattern? It may sound so, but both patterns are fundamentally different. In short,
- Retry Pattern : Allows retry when expecting to succeed
- Circuit Breaker : Prevents access when likely to fail.
Circuit Breaker is usually implemented as a state machine with three key states
In this state, the circuit is inactive and allows operations to be invoked by the application. It silently tracks the failures via a counter and when the counter passes a threshold, the State of Circuit breaker is changed to Open. The failure counter could be reset periodically to ensure occasional failures are considered. The Circuit breaker is tripped only when a certain number of errors occur within a specified span of time.
When the circuit breaker is tripped, or in other words, when it is in Open State, it is assumed that the underlying service or operation provider is unable to process the request and is likely to fail. Considering the possible failure, the Circuit breaker prevents access to service and returns an early error. The early failure ensures expensive resources aren’t tied up for an operation that is likely to fail.
Once the Circuit Breaker is in Open State, a timer is started which would run for a specified period of time. This time is assumed to be the likely time which the underlying service could recover. The duration of the waiting period could be preconfigured or could be dynamically altered as the application gains knowledge of the underlying services and recent failures.
After the timer elapses the specified period of time, the State of the Circuit breaker is set as Half-Open.
- Half Open
Half Open is a special state which allows a limited number of requests. If the request encounters a failure, the state of the Circuit Breaker is set back to Open State and the timer is restarted. If on other hand, all the requests (from the limited request pool) succeed, the Circuit Breaker is set to Closed State.
The Half Open State restricts recovering services from being flooded with requests. Flooding the recovering service could lead it back to fail again and hence should be aided in recovery by allowing only a limited amount of requests to be processed.
The circuit Breaker provides stability while the service recovers and minimizes the performance issues. Furthermore, the Circuit Breaker’s state changes could be logged and could be used as an indication of the health of the underlying service.
The Circuit Breaker could also expose the option for the administrator to manually reset the circuit and is quite useful when the administrator is fully aware of the recovery. Also, the trigger parameters could be configured depending on the type of exception encountered. This is also applicable for evaluating responses from the service to detect an impending failure.
The following articles describe the implementation of a Circuit breaker using the Ocelot and Polly libraries.