Handling FallBack and TimeOut in MicroService using Hystrix
Guys,
Let’s look into a useful feature that we should use while working with microservice architecture.
While working with this type of architecture, especially you are exposing your services as an API and available for third party use you have to be careful to provide proper response and in timely fashion.
Goal
Our primary goal is to learn
- Use of FallBack method in case of service is not available.
- Use of TimeOut mechanism if API will not respond in predefined time period.
To achieve our goal we are using Hytrix which is also comes under Netflix’s umbrella.
What is Hytrix
Hytrix is a library to handle fallback, manage isolation, concurrency and provide multiple options to manage failure.
Official git of Hytrix is : https://github.com/Netflix/Hystrix
How to do
In this example we will see how to enable hystrix and what changes are required to handle fallback in case of service is not available and in case of timeout occurred.
You can clone repository from below git.
GitHub Repo: https://github.com/yogeshmprajapati/kode12-spring-boot.git
Git Module: spring-boot-hystrix
pom.xml
Add following dependency in you pom.
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix</artifactId> </dependency> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Camden.SR6</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
application.properties
server.port=8080
TestController.java
package com.kode12.controller; import java.util.ArrayList; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate; import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty; @RestController public class TestController { @Autowired RestTemplate restTemplate; @RequestMapping(value = "/doTest") /*Line 22*/ @HystrixCommand(fallbackMethod = "getDataFallBack", commandProperties = { /*Line 23*/ @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1000") }) public List<String> doTest() { return restTemplate.getForObject("http://localhost:8080/getData", List.class); } @RequestMapping(value = "/getData") public List<String> getData() { try { Thread.sleep(1200); } catch (InterruptedException e) { e.printStackTrace(); } List<String> list = new ArrayList<String>(); list.add("Live 1"); list.add("Live 2"); list.add("Live 3"); return list; } public List<String> getDataFallBack() { List<String> list = new ArrayList<String>(); list.add("FallBack 1"); list.add("FallBack 2"); list.add("FallBack 3"); return list; } }
Here, we have created 3 different method
- doTest: Rest method used to invoke method from outside.
- getData: is also a rest method but we are calling it using doTest method via RestTemplate to create fallback and timeout scenario.
- getDataFallBack: which is invoked in case of fallback and timeout scenario.
Now, lets understand what annotation we used with doTest method(Line no 22 & 23) in detail.
@HystrixCommand(fallbackMethod = "getDataFallBack", commandProperties = { @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1000") })
@HystrixCommand:
used to provide metadata/configuration to particular methods.
Attributes:
fallbackMethod
: value of this attribute is name of method which needs to be invoke in case of fallback.
commandProperties
: We can define multiple properties using @HystrixProperty
Annotation. Here we have multiple option available, it is same like key-value pair. Here we used execution.isolation.thread.timeoutInMilliseconds
attribute with value 1000 means the RestTemplate
wait for 1000 ms and once this time is over than it perform fallback logic.
You can find out more option here.
SpringBootHystrixApplication.java
Class having main method to run an application.
package com.kode12; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; import org.springframework.context.annotation.Bean; import org.springframework.web.client.RestTemplate; @SpringBootApplication @EnableCircuitBreaker public class SpringBootHystrixApplication { public static void main(String[] args) { SpringApplication.run(SpringBootHystrixApplication.class, args); } @Bean public RestTemplate restTemplate() { return new RestTemplate(); } }
The notifiable thing here is @EnableCircuitBreaker
annotation. It apply circuit breaker mechanism to methods using Hystrix library.
Run an application
Run your application using main method and hit URL below to your favorite browser.
Url: http://localhost:8080/doTest
Output:
Here it invoke fallback method as we have configured 1000 ms
for timeout and in getData
method we have explicitly add delay of 1200 ms
using Thread.sleep(1200)
.
If we remove Thread.sleep(1200)
from code than output will be as follow
You can change url for restTemplate.getForObject
method and test it for fallback.
Share current post by copy: https://goo.gl/l5Ia4D
Happy Learning!
Thanks,
Yogesh P