In the distributed environment it is ubiquitous for a server/system to make remote calls to many processes running on different machines over the network. And when there are calls over the network, there is a very high chance that calls to remote resources or services might fail and this failure can be due to transient faults, such as slow network connections, timeouts, or the resources being over-committed or temporarily unavailable. Generally, these types of faults generally correct themselves after a short period of time.
However, there are situations where failure takes a long to fix itself. And in such cases, if the caller keeps on continually retrying an operation that is unlikely to succeed, hence precious resources such as threads might be consumed. Also, this might lead to resource exhaustion, which would make the calling service unable to handle other requests, and in turn failure of one service can result in cascading failures across multiple systems.
Hence to rescue us from situations like this and save CPU resources, the Circuit Breaker design pattern was introduced.
The Circuit Breaker design pattern is used to prevent applications from repeatedly invoking services that are likely to fail and allow applications to continue without waiting for the fault to be fixed or wasting CPU resources.
The basic idea behind the circuit breaker is similar to an electrical circuit breaker. It acts as a proxy for operation and monitors the number of failures. Once the failures reach a certain threshold, the circuit breaker trips, and further calls are returned returns in an exception.
The Circuit Breaker proxy also enables an application to detect whether the fault has been resolved and the problem appears to be fixed, the application can again try invoking the service.
Different Stages Of Circuit Breaker
The proxy circuit breaker mimics the behavior of an electric circuit breaker and can have the following states:
- Half Open
When everything is operating smoothly then the circuit breaker is in a closed state. The request from the application is routed to the server. The proxy maintains a count of the number of recent failures, and if the call to the server/resource is unsuccessful the proxy increments the failure count. If the number of failures in a given interval increases beyond the threshold, the circuit breaker trips and goes into an open state.
When the circuit breaker is in the open state, all the requests from the requesting application fail immediately and an error is returned.
Half Open State
After the timeout interval elapses, the circuit breaker moves into a half-open state. In this state, a limited number of requests are allowed from the application to invoke the operation. If these requests are successful then it’s assumed that the fault that was causing the failure is resolved and the circuit breaker switches to the Closed state. However, if requests continue to fail, the circuit breaker again goes into the Open state.
Advantages and Disadvantages of Circuit Breaker
We have already discussed the circuit breaker pattern and various states they can switch into, now let’s discuss the advantages and disadvantages of this pattern.
- Circuit breaker provides, a good way to make a system fault tolerant.
- Circuit breakers help to reduce resources tied up in operations that are likely to fail.
- The pattern is customizable and can be adapted according to the type of possible failure.
- It also provides stability while the system recovers from a failure and minimizes the impact on performance.
- Testing can be harder than it appears.
- It is challenging to choose timeout values without creating false positives or introducing excessive latency.
- A request might fail for many reasons, some of which might indicate a more severe type of failure than others. A circuit breaker might be able to examine the types of exceptions that occur and adjust its strategy depending on the nature of these exceptions.