Circuit breaker

Services sometimes need to collaborate with each other when they need to handle requests. In such cases, there is a very high scenario that the other service is not available, is showing high latency, or is unusable. This pattern essentially solves this issue by introducing a breakage in the circuit that stops propagation in the whole architecture:

  • Problem: In the microservices architecture when there is inter-services communication, a remote call needs to be invoked instead of an in-memory call. It may so happen that the remote call may fail or reach a timeout limit and hang without any response. Now in such cases when there are many callers, then all such locked threads that you can run out of resources and the whole system will become unresponsive.
  • Solution: A very primitive idea for solving this issue is introducing a wrapper for a protected function call, it monitors for failures. Now this wrapper can be triggered via anything such as certain threshold in failures, database connection fails, and so on. All further calls will return with an error and stop catastrophic propagation. This will trip the circuit open, and while the circuit is open, it will avoid making the protected call. The implementation is done in the following three stages just as in an electric circuit. It is in three stages: Closed State, Open State, and Half-Open State, as explained in the following diagram:

Here is an example for implementation in Node.js: Hystrix is open sourced by Netflix https://gist.github.com/parthghiya/777c2b423c9c8faf0d427fd7a3eeb95b

  • Take care of: The following needs to be taken care of when you want to apply the circuit breaker pattern:
  • Since you are invoking a remote call, and there may be many remote call invocation asynchronous and reactive principles for using future, promises, async, and await is must.
  • Maintain a queue of requests; when your queue is overcrowded, you can easily trip the circuit. Always monitor the circuit, as you will often need to activate it again for an efficient system. So, have a mechanism ready for reset and failure handlers.
  • You have a persistent storage and network cache such as Memcache or Redis to record availability.
  • Logging, exception handling, and relaying failed requests.
  • When to use: In the following use cases, you can use the circuit breaker pattern:
  • When you don't want your resources to be depleted, that is, an action that is doomed to fail shouldn't be tried until it is fixed. You can use it to check the availability of external services.
  • When you can compromise a bit on performance, but want to gain high availability of the system and not deplete resources.
  • When not to use: In the following scenarios, it is not advisable to introduce the circuit breaker pattern:
  • You don't have an efficient cache layer that monitors and maintains states of services for a given time for requests across the clustered nodes.
  • For handling in-memory structures or as the substitute for handling exceptions in business logic. This would add overhead to performance.