How to embed Hystrix into existing Spring applications

2 Minutes reading time

Netflix Hystrix is a very powerful framework to build fault tolerant and resilient applications. It provides common implementations for patterns like Timeout, CircuitBreaker and others. It also comes with nice monitoring capabilities using the Hystrix Dashboard or even JMX.

Now, Hystrix should be used as a kind of decorator around interfaces or gateways to other (sub) systems. The tricky part is to do this in a non invasive manner. And here comes Spring and AOP to play:

Consider the following class:

package de.mirkosertic;

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

import java.util.Random;

@Service
@Scope("singleton")
public class RandomBean {

    private final Random random;

    public RandomBean() {
        random = new Random();
    }

    @CircuitBreaker
    public String random() {
        return "Random " + random.nextInt();
    }
}

The RandomBean can be a gateway to some remote service. Do you see the @CircuitBreaker annotation? This marks the method as to be “protected” and “monitored” by Hystrix. But what is going on under the hood? The @CircuitBreaker annotation works together with an AOP around advice, and this advice encapsulates the whole Hystrix logic, as seen here:

package de.mirkosertic.aspect;

import com.netflix.hystrix.HystrixCommand;
import com.netflix.hystrix.HystrixCommandGroupKey;
import com.netflix.hystrix.HystrixCommandKey;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;

import org.springframework.stereotype.Component;

@Aspect
@Component
public class CircuitBreakerAspect {

    @Around("@annotation(de.mirkosertic.CircuitBreaker)")
    public Object circuitBreakerAround(final ProceedingJoinPoint aJoinPoint) throws Throwable {
        String theShortName = aJoinPoint.getSignature().toShortString();
        HystrixCommand.Setter theSetter =
                HystrixCommand.Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey(theShortName));
        theSetter = theSetter.andCommandKey(HystrixCommandKey.Factory.asKey(theShortName));
        HystrixCommand theCommand = new HystrixCommand(theSetter) {
            @Override
            protected Object run() throws Exception {
                try {
                    return aJoinPoint.proceed();
                } catch (Exception e) {
                    throw e;
                } catch (Throwable e) {
                    throw new Exception(e);
                }
            }
        };
        return theCommand.execute();
    }
}

Nice! But how to we add Hystrix monitoring capabilities to our app? We just need to add a small Servlet to our web.xml, as seen here:

    <servlet>
        <display-name>HystrixMetricsStreamServlet</display-name>
        <servlet-name>HystrixMetricsStreamServlet</servlet-name>
        <servlet-class>com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>HystrixMetricsStreamServlet</servlet-name>
        <url-pattern>/hystrix.stream</url-pattern>
    </servlet-mapping>

And the monitoring can be done using the Hystrix Dashboard app, as seen here:

hystrixdashboard

Very nice! Using the Dashboard, we can monitor the throughput of the service interface and we can also see the status of the circuit breaker and other statistics. The sources and examples of this tutorial are available at github.com/mirkosertic/HystrixSpring. Yes, resilience, here we go!

Git revision: 0972269

Loading comments...