A design pattern is a generic, reusable solution for a commonly occurring design problem. There are many design patterns in Java. The Circuit breaker pattern is one of such patterns which is applicable for applications that interacts with each other using remote service calls. It is widely used in Microservice architecture.
The enterprise applications used to be large monolithic ones, which usually followed a Model - View - Controller pattern. The application will be built as a large package following this pattern. So, if a failure of one part of the system e.g.: report generation may affect the entire system as the modules are tightly coupled. Recently there was a shift to develop applications as a collection of small services or microservices each of which performs some certain functionality. Thus, microservices together form a large enterprise application. The communication among these services is made possible by web services, messaging systems etc. The main advantage of this approach is we can manage each service quite independently. I.e.if a service requires more resources, we can easily allot to it.
What is Circuit breaker pattern?
In Microservices architecture, a process needs to make calls to another process running in a remote machine. These remote calls may fail sometimes due to connectivity issues, or remote system failure etc. This service failures could affect the user experience. For example, if your application has 10 services that expects have 99.99% of uptime. This means 99.9% uptime for entire system. If your application has a billion requests to serve in a month, we can expect 1,000,000 failures in a month. This could be an hour of outage in month. The number will be more as the dependent services and user requests increases. Also, if a service fails, there is a chance that the entire user request will be blocked. So here comes the need of designing the system for resiliency.
So, we need to detect the failures immediately and apply corrective measures so that that system performance will not be affected. So here a circuit breaker pattern can be applied to redirect the traffic to a fallback path. The solution also can be extended to monitor the health of failed service and once it is back to normal, traffic can be resumed.
In this pattern we will bind the remote calls under a circuit breaker object, which monitor for any service call failures. If the failures pass a threshold then further calls will be redirected to a fallback logic. This will make sure that service failures will not cripple the entire application itself. Netflix offers Hystrix library for this purpose
Hystrix was an in-house product of Netflix API team that worked on resiliency engineering. It has following capabilities.
- Service failure protection and handle it such that the failure will not propagate in the system.
- Fail fast and rapid recovery.
- Real-time monitoring and alerting.
- Will tolerate the failures till a certain threshold after that the fallback methods will be invoked.
Now it is time to see Hystrix in action. Let us create a sample Spring boot application that uses Hystrix. Create a Spring boot application using your editor.
1. Add dependencies
Add below dependencies in your pom.xml. The spring-cloud-starter-netflix-hystrix will bring in the necessary Hystrix dependency for our project.
2. Now add a SpringBootApplication class. This will be the starting point for this Spring boot app execution.
The @EnableCircuitBreaker annotation will tell the Spring that the application has circuit breakers (here Hystrix), so that the monitoring, logging etc. can be done. This class is also annotated as @RestController, which will mark it as a controller as well. The endpoint "/test-hystrix" will take GET requests and send the response as a String. The endpoint will invoke a service method. Now let us see this service method.
3. The TestService class contains the call to an external free REST API that returns a fake JSON response. Here we will use https://reqres.in/api/products/3.
The @HystrixCommand annotation is added to readProductDetails() method. Now Hystrix will watch for the failing calls to that method. If the failure reaches a threshold value, the testFallBack() method will be invoked. The readProductDetails() method will call the third party API and return the response.
4. Now add server.port=8080 in our application.properties file so that the application will be up in the port 8080.
5. To test this invoke http://localhost:8080/test-hystrix in your browser. This will produce a fake JSON as follows.
6. Now if we don't have the external call successful, we will get a response as "product not found.” Her we can see that the fallback method will be invoked in case of a failure.
In order to monitor the service health, we can use the Hystrix dashboard. This is a UI dashboard that gives some important metrics of service health. To enable this, we need to add spring-cloud-starter-hystrix-dashboard and spring-boot-starter-actuator dependencies in our pom.xml. The @EnableHystrixDashboard needs to be added in our HystrixApplication class. Once the application is started hit on the http://localhost:8080/hystrix to view the dashboard in a browser.
In this tutorial we have seen what a Microservice is and how a circuit breaker pattern is of great help to improve the resiliency of our Java application development. Netflix Hystrix is a library that can be configured as a circuit breaker in the microservice. The efficient use of Hystrix will ensure a smooth customer experience. Hystrix also provides options to monitor the health of our services. Thereby tools like Hystrix are a must have for any well engineered microservice application.