Thursday, October 22, 2015

Hystrix demistified

Hystrix is simple in itself and very easy to understand, still some get confused about how it works.
So let me give a simple example of how it works.
I have taken below example from : Hystrix site Getting-Started
public class CommandHelloWorld extends HystrixCommand<String> {

    private final String name;

    public CommandHelloWorld(String name) {
        super(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"));
        this.name = name;
    }

    @Override
    protected String run() {
        // a real example would do work like a network call here
        return "Hello " + name + "!";
    }
}

String s = new CommandHelloWorld("Bob").execute();
Let us demystify this code:

First:

You need to extend the HystrixCommand to use Hystrix circuit breaker.
HystrixCommand<String>  // This statement tells what your Hystrix command is going to return when your execute it. (Return value of run() method)

HystrixCommand<AnyObject>

HystrixCommand<Anything> 

Second:

Constructor behave as the entry point of your Hystrix Command. You should define it in such a way that values passed can be used to:
1) defining Hystrix Command name, group name , Cache key etc.
2)  help execute the run() method to do the actual task by providing needed element.
    public CommandHelloWorld(String name) {
        }

Example 1:

In above example this parameter is used in run method.
    public CommandHelloWorld(String name) {
    super(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"));
    }

Example 2:

The parameter here are used to define Hystrix Command and are used in run method to make a http call.
   public CommandHelloWorld(String groupKeyName,String commandName, HttpClient httpClient, HttpContext httpContext, HttpRequestBase httpRequest) {
        super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey(groupKeyName)).andCommandKey(HystrixCommandKey.Factory.asKey(commandName)));
    }
    

Example 3:

The parameter here are used to define Hystrix Command and are used in run jdbc call.
public CommandHelloWorld(String groupKeyName,String commandName, JDBCTemplate jdbcTemplate) {
        super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey(groupKeyName)).andCommandKey(HystrixCommandKey.Factory.asKey(commandName)));
    }

Third:

This call is to configure the HystrixCommand.
super(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"));  // this define the group name of your Hystrix command.

Hystrix define two constructror for configuration:

protected HystrixCommand(HystrixCommandGroupKey group) { // Example 1 
        this(new HystrixCommand.Setter(group, null));
    }

protected HystrixCommand(HystrixCommand.Setter setter) { // Example 2 or 3
        this(setter.groupKey, setter.commandKey, setter.threadPoolKey, (HystrixCircuitBreaker)null, (HystrixThreadPool)null, setter.commandPropertiesDefaults, setter.threadPoolPropertiesDefaults, (HystrixCommandMetrics)null, (HystrixCommand.TryableSemaphore)null, (HystrixCommand.TryableSemaphore)null, (HystrixPropertiesStrategy)null, (HystrixCommandExecutionHook)null);
    }

Fourth:

To implement the HystrixComman override the run() method. This is where you will do all the task as per your requirement.
@Override
    protected String run() {
        // a real example would do work like a network call here
        return "Hello " + name + "!";
    }

Fifth:

The above created command be used like this :String s = new CommandHelloWorld("Bob").execute(); // this will internally call the run() method

No comments:

Post a Comment