Spring Boot - Hystrix
In microservice architecture, a single client request from one microservice might need to communicate to other microservice. Ideally we should try to avoid such direct dependencies on other microservices, at times it is unavoidable. So if a microservice gets down then issue may cascade up to upstream services. To handle such issues Netflix came up with Hystrix library.
Hystrix is a library designed to isolate access points to services or third party libraries. Avoids cascading failure and enables resilience in distributed systems specially micro service architecture where failure is inevitable.
In this blog, I will explain you How we can implement Hystrix in Spring Boot application.
Add the Spring Cloud Starter Hystrix dependency to your build configuration file.
For Maven users add following dependency in pom.xml file org.springframework.cloud spring-cloud-starter-hystrix For Gradle users add following dependency in build.gradle file compile('org.springframework.cloud:spring-cloud-starter-hystrix')
Now, add @EnableHystrix annotation in your main Spring Boot application class file. The @EnableHystrix annotation enables Hystrix functionalities into your Spring Boot application. Below is the code for main Spring Boot application class file
package com.oodles.hystrixapp; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.hystrix.EnableHystrix; @SpringBootApplication @EnableHystrix public class SpringBootHystrixDemoApplication { public static void main(String[] args) { SpringApplication.run(SpringBootHystrixDemoApplication.class, args); } }
An example in which our VehicleService communicates with other microservice and gives user friendly message if other microservice doesn't respond.
package com.oodles.hystrixapp.VehicelService; import java.util.Date; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.core.ParameterizedTypeReference; import org.springframework.http.HttpMethod; import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate; import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; @Service public class VehicelService { @Autowired RestTemplate restTemplate; @HystrixCommand(fallbackMethod = "callStudentServiceAndGetData_Fallback") public String callCarServiceAndGetCarList() { System.out.println("Getting Car List "); String response = restTemplate .exchange("http://localhost:8098/getCarList" , HttpMethod.GET , null , new ParameterizedTypeReference() { }).getBody(); System.out.println("Response Received as " + response + " - " + new Date()); return " Car List " + response + " - " + new Date(); } @SuppressWarnings("unused") private String callCarServiceAndGetCarList_Fallback() { System.out.println("Car Service is down!!! fallback route enabled..."); return " No Response From Car Service at this moment. " + new Date(); } @Bean public RestTemplate restTemplate() { return new RestTemplate(); } }
An example to set timeout for a request if it doesn't respond in 3 seconds
@RequestMapping(value = "/") @HystrixCommand(fallbackMethod = "fallback_springBootHystrixDemo", commandProperties = { @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000") }) public String springBootHystrixDemo() throws InterruptedException { Thread.sleep(5000); return "Welcome Spring Boot Hystrix Demo"; } private String fallback_springBootHystrixDemo() { return "Request Failed!!! It's taking more then 3 seconds to get response"; }
Thanks,