Netflix OSS: A beginner's guide [pt4]

Netflix OSS: A beginner's guide [pt4]

When a system grows, you need some kind of monitoring as well. If you have a monolithic app, that is not really a hard task, but when it comes to microservices word, things change.
How to keep track of hundreds of instances? How do you know if one of them fails?
Netflix solve this issue with Hystrix and Turbine.

Hystrix

Hystrix is a library designed " to control the interactions between distributed services providing greater tolerance of latency and failure". In short, Hystrix can wrap API calls ensuring that if something goes wrong, you will 1) know about right away and 2) provide a fallback method in order to prevent cascading failure. It does it through Circuit breaker

Turbine

But how do you aggregate all Hystrix endpoints from hundreds of services? Thats a job for Turbine. Hystrix provide information through Server-Sent Event (SSE) JSON data and Turbine can aggregate them.

Putting them to work

So far we have Eureka as service discovery backend, Zuul proxying our API calls and one instance of contacts-service, where the game happens.
Now, we want to monitor calls to our service and not care if there are 1 or 1000 instance of it.

in contact's pom.xml lets add the Hystrix dependice with

<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>

and in the main class, annotate with @EnableCircuitBreaker.
To wrap a function with circuit breaker, you should provide a fallback function. In our component responsible for load the contacts, lets do the following:

@HystrixCommand(fallbackMethod="getUsersFallback")
	public Iterable<Contact> getContacts() throws IOException{
		return repository.findAll();
	}
	public Iterable<Contact> getUsersFallback(){
		return new ArrayList<>();
	}

the @HystrixCommand annotation demands a value for fallbackMethod option. This method should accept the same params as the original function, in types and numbers.
You also need to add Spring Boot Actuator as dependency to the app in order to expose the Hystrix endpoint.

Hystrix Dashboard

We will have one single app for all: the dashboard and the aggregator. To do so, lets got to start.spring.io and create a new app as follows:

Download the project and annotate its main class with

@EnableHystrixDashboard
@EnableTurbine
@EnableEurekaClient

The first two annotations are self explanatory and the last one is needed because Turbine will connect to Eureka, ping all services available, searching for any Hystrix endpoint.
Here is the configuration for Eureka and Turbine:

server.port: 8090  
eureka:
  client:
    serviceUrl:
      defaultZone: http://127.0.0.1:8761/eureka/
  instance:
    preferIpAddress: false

turbine:
  aggregator:
    clusterConfig: CONTACTS-SERVICE
  appConfig: CONTACTS-SERVICE

The first section we know from past blog posts: connecting to Eureka. The second is new. We are telling Turbine what and how to aggregate our Hystrix endpoints. clusterConfig is the name of the cluster, it is how we are going to access it and appConfig is the name of the service we want to aggregate. We can have multiple services aggregated in the same Turbine app with, for example, appConfig: customers,stores,ui,admin

Now, lets deploy everything. and access the the Hystrix Dashboard on 8090:

in the field available, point it to Turbine stream endpoint. You will be redirected to the dashboard. Do some calls to the contacts endpoints and you will see something like this

The dashboards shows that our method getContacts is working fine (as the circuit is closed) and we have one host in the aggregator. If you deploy more instances you will see the Hosts number increasing. Here I deployed one more and the numbers changed:

And thats it, using Hystrix you can have a basic monitoring deployed in a couple of hours that works independently from the number of hosts you have and in real time.

Icons created by Freepik - Flaticon