Spring Cloud supports Netflix utilities which has produced a library based on the circuit-breaker pattern implementation called Hystrix. In this tutorial we will learn how we

can use the Hystrix library to prevent cascading failures, which is very common in the microservice architecture where we have several individual services hosted on different machines across a network.

Start by creating your project in order to include web and cloud-hystrix dependencies.

spring init -dweb,cloud-hystrix demo-hystrix

Now open your project named "demo-hystrix" in your favourite editors. Here is the list of dependencies that will be added:

<dependencies>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-web</artifactId>
	</dependency>
	<dependency>
		<groupId>org.springframework.cloud</groupId>
		<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
	</dependency>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-test</artifactId>
		<scope>test</scope>
	</dependency>
</dependencies>

Now the classes. Let's add first the Main class:

package com.example.demohystrix;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;

@EnableHystrix
@SpringBootApplication
public class DemoApplication {

	public static void main(String[] args) {
		SpringApplication.run(DemoApplication.class, args);
	}

}

The @EnableHystrix is used to implement the circuit breaker pattern specifically with Hystrix on the classpath.

And here is a sample REST Controller:

package com.example.demohystrix;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;


import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;

@RestController
public class SampleController
{
    @RequestMapping(value = "/")
    @HystrixCommand(fallbackMethod = "planb", commandProperties = {
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1000")
    })
    public String hello() throws InterruptedException {
        Thread.sleep(2000);
        return "Hello World";
    }
    private String planb() {
        return "Sorry our Systems are busy! try again later.";
    }
}

As you can see Hystrix provides an annotation, @HystrixCommand , which we can use at the service layer to add the functionality of the circuit-breaker pattern. Should the method mapped with @HystrixCommand fail, a fallback method execution is configured. In our case, if 1000ms of time passes, the method "planb" will be executed.

If you run the application, you will see:

$ curl http://localhost:8080
Request fails. It takes long time to response

Error propagation

The @HystrixCommand annotation has the ability to specify exceptions types that should be ignored:

@HystrixCommand(ignoreExceptions = {BadCustomerIdException.class})
public Customer findCustomerId(String id) {
return customerService.findCustomerById(id);
}

If findCustomerId throws an exception of the BadCustomerIdException type, then this exception will be wrapped in HystrixBadRequestException and be-thrown without triggering the fallback logic.

Source code

The source code for this example is available at: https://github.com/fmarchioni/masterspringboot/tree/master/hystrix/demo-hystrix

FREE WildFly Application Server - JBoss - Quarkus - Drools Tutorials