Spring Cloud Netflix OSS + Netflix Zuul API Gateway + Netflix Eureka Discovery Server + Netflix Hystrix (Circuit Breaker) + Turbine + Example

In this blog we will learn, Netflix Circuit Breaker component implementation while invoking underlying microservices.

  • Hystrix is a latency and fault tolerance library designed to isolate points of access to remote systems, services and 3rd party libraries
  • It stop cascading failure and enable resilience in complex distributed systems where failure is inevitable.
  • Usually for systems developed using Microservices architecture, there are many microservices involved and these microservices collaborate with each other. Here, Hystrix comes to the picture. In below working example we will learn in details.

MicroServices Architecture Overview (Spring Cloud Netflix OSS)

MicroServices Architecture Overview (Spring Cloud Netflix OSS)

In this example, we have two microservices (student and skillstechnologies), where first student microservices is dependent on skillstechnologies for fetching the student course details. Here, we are adding servicedelegate class for consuming skillstechnologies rest api named /getStudentCourse/{name} through RestTemplate.

Why Hystrix?

Now, suppose due to some reason skillstechnogies service (/getStudentCourse/{name}) throws an exception. In this case using Hystrix we are defining a fallback method, it will return some value on failure.

Circuit Breaker, How it works?

When, we call to a particular service exceed circuitBreaker.requestVolumeThreshold (default: 20 requests) and the failure percentage is greater than circuitBreaker.errorThresholdPercentage(default: >50%) in a rolling window defined by metrics.rollingStats.timeInMilliseconds (default: 10 seconds), the circuit opens and the call is not made. In cases of error and an open circuit, a fallback can be provided by the developer.

How to Customize behavior of Hystrix?

It is possible by using @HystrixProperty or through application.properties

@HystrixCommand(fallbackMethod = "callStudentServiceAndGetData_Fallback", commandProperties = {
   @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000"),
 @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "60") })

Technology stack

Java 8
Maven 3.5.0
Spring Boot 2.0.5.RELEASE
Eclipse
Netflix Eureka as Service Registry Server
Netflix Ribbon as Client Side Load balancer
Netflix Hystrix as circuit breaker
2 Microservices (student & skillstechnologies)

Application Setup

spring-boot-zuul-gateway-proxy 1 node (localhost:8989)
spring-boot-zuul-gateway-proxy-eureka-server 1 node (localhost:9090)
spring-boot-zuul-gateway-proxy-student-service 1 node (localhost:8930)
spring-boot-zuul-gateway-proxy-skillstechnologies-service 1 node (localhost:8940)

Note: for step by step configurations click on my previous blog: Spring Cloud Netflix OSS + Netflix Zuul API Gateway + Netflix Eureka Discovery Server + 2 x Microservices + Example

Microservice: spring-boot-zuul-gateway-proxy-student-service changes

Note: there is no any change in any properties file.

Microservice: Maven File (pom.xml)

Following highlighted maven dependencies need to be added in pom.xml file of spring-boot-zuul-gateway-proxy-student-service microservice

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.example</groupId>
	<artifactId>spring-boot-zuul-gateway-proxy-student-service</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>spring-boot-zuul-gateway-proxy-student-service</name>
	<description>Project for Spring Boot Student Service</description>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.1.1.RELEASE</version>
		<relativePath /> <!-- lookup parent from repository -->
	</parent>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
		<spring-cloud.version>Greenwich.RELEASE</spring-cloud.version>
	</properties>

	<dependencies>
          <dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-rest</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-actuator</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-netflix-turbine</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.springframework.cloud</groupId>
				<artifactId>spring-cloud-dependencies</artifactId>
				<version>${spring-cloud.version}</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>	
</project>

Microservice: Service Delegate Layer (StudentServiceDelegate.java)

package com.the.basic.tech.info.studentinfoservice.delegate;

import java.util.Date;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;

@Service
public class StudentServiceDelegate {
	private static final Logger logger = LoggerFactory.getLogger(StudentServiceDelegate.class);
	@Autowired
	RestTemplate restTemplate;

	@HystrixCommand(fallbackMethod = "callStudentServiceAndGetData_Fallback", commandProperties = {
			@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000"),
			@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "60") })
	public String callStudentServiceAndGetData(String name) {
		logger.info("Getting StudentSubject details for {}", name);
		String response = restTemplate
				.exchange("http://localhost:8989/portal/skillTechService/skillstech/getStudentCourse/{name}",
						HttpMethod.GET, null, new ParameterizedTypeReference<String>() {
						}, name)
				.getBody();

		logger.info("Response Received as " + response + " -  " + new Date());

		return "NORMAL FLOW. Student Course: " + response;
	}

	@SuppressWarnings("unused")
	private String callStudentServiceAndGetData_Fallback(String name) {
		logger.info("Skills Tech Service is down!!! Hystrix fallback route enabled for this service.");
		return "CIRCUIT BREAKER ENABLED. No Response From Skills Tech Service at this moment. Service will be back Shortly.";
	}

	@Bean
	public RestTemplate restTemplate() {
		return new RestTemplate();
	}
}

Microservice: How to call Service Delegate Layer

package com.the.basic.tech.info.studentinfoservice;

import java.util.Date;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.the.basic.tech.info.studentinfoservice.delegate.StudentServiceDelegate;

@RestController
@SpringBootApplication
@EnableHystrixDashboard
@EnableCircuitBreaker
public class StudentServiceApp {
	private static final Logger logger = LoggerFactory.getLogger(StudentServiceApp.class);
	@RequestMapping(value = "/echoStudentName/{name}")
	public String echoStudentName(@PathVariable(name = "name") String name) {
		return "Hello  " + name + " Responsed on : " + new Date();
	}

	@Autowired
	StudentServiceDelegate studentServiceDelegate;
	
	@RequestMapping(value = "/getStudentDetails/{name}")
	public Student getStudentDetails(@PathVariable(name = "name") String name) {
		logger.info("Going to call skillstechnologies /getStudentCourse/ service (Hystrix Enabled) to get data!");
		String cls = studentServiceDelegate.callStudentServiceAndGetData(name);
		logger.info("course/class value from skillstechnologies microservice {}", cls);
		return new Student(name, "Northridge, CA", cls, "Block-E", "California State University");
	}	

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

class Student {
	String name;
	String address;
	String cls;
	String university;
	String block;	

	public Student(String name, String address, String cls, String block, String university) {
		super();
		this.name = name;
		this.address = address;
		this.cls = cls;
		this.block = block;
		this.university = university;
	}

	public String getName() {
		return name;
	}

	public String getAddress() {
		return address;
	}

	public String getCls() {
		return cls;
	}
	public String getUniversity() {
		return university;
	}

	public String getBlock() {
		return block;
	}	

}

Microservice: SpringEurekaClientSkillTechServiceInfoContributor implements InfoContributor

package com.the.basic.tech.info.studentinfoservice.delegate;

import java.util.Collections;

import org.springframework.boot.actuate.info.Info;
import org.springframework.boot.actuate.info.InfoContributor;
import org.springframework.stereotype.Component;

@Component
public class SpringEurekaClientSkillTechServiceInfoContributor implements InfoContributor {

	@Override
	public void contribute(Info.Builder builder) {
		builder.withDetail("details",
				Collections.singletonMap("description", "This is the Student microservice, which discovery server awares, and this service will Call SkillsTechnologies microservice."));
	}

}

Microservice: spring-boot-zuul-gateway-proxy-skillstechnologies-service changes

We need to add one more rest interface named /getStudentCourse/{name}/ for retruning the course name to the student microservice.

Microservice: Add getStudentCourse Rest API in SkillsTechnologiesController.java

package com.the.basic.tech.info.skillstechnologies.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/skillstech")
public class SkillsTechnologiesController {
	private static final Logger logger = LoggerFactory.getLogger(SkillsTechnologiesController.class);

	@GetMapping("/getSkills")
	public String getSkills() {
		logger.info("Inside getSkitlls Method.");
		// we can implement DB layer for fetching below details
		return "Java, J2EE, Spring, Spring-Boot, Microservices, Docker, Kubernetes.";
	}
	
	@RequestMapping(value = "/getStudentCourse/{name}")
	public String getStudentDetails(@PathVariable(name = "name") String name) {		
		return "MBA";
	}
}

Applications (microservices) Deploy, Run & Test

Hystrix: Normal Flow (CIRCUIT CLOSED State)

When both the microservices are up and running susccessfully.

Test /student/getStudentDetails microservice

http://localhost:8989/portal/student/getStudentDetails/The%20Basic%20Tech%20Info

Test /student/getStudentDetails microservice

Hystrix: CIRCUIT BREAKER ENABLED Flow (CIRCUIT OPEN State)

Suppose skillstechnologies microservice is down. Just stop the microservice and see the result.

2021-06-21 00:18:19.166  INFO 18252 --- [       Thread-6] o.s.c.n.e.s.EurekaServiceRegistry        : Unregistering application SKILLTECHNOLOGIESSERVICE with eureka with status DOWN
2021-06-21 00:18:19.168  WARN 18252 --- [       Thread-6] com.netflix.discovery.DiscoveryClient    : Saw local status change event StatusChangeEvent [timestamp=1624214899168, current=DOWN, previous=UP]
2021-06-21 00:18:19.170  INFO 18252 --- [nfoReplicator-0] com.netflix.discovery.DiscoveryClient    : DiscoveryClient_SKILLTECHNOLOGIESSERVICE/INDSNOI6N6RMH2.AMERICAS.GLOBAL.NTTDATA.COM:skillTechnologiesService:8940: registering service...
2021-06-21 00:18:19.179  INFO 18252 --- [nfoReplicator-0] com.netflix.discovery.DiscoveryClient    : DiscoveryClient_SKILLTECHNOLOGIESSERVICE/LOCALHOST:skillTechnologiesService:8940 - registration status: 204
2021-06-21 00:18:19.187  INFO 18252 --- [       Thread-6] o.s.s.concurrent.ThreadPoolTaskExecutor  : Shutting down ExecutorService 'applicationTaskExecutor'
2021-06-21 00:18:19.204  INFO 18252 --- [       Thread-6] com.netflix.discovery.DiscoveryClient    : Shutting down DiscoveryClient ...
2021-06-21 00:18:22.208  INFO 18252 --- [       Thread-6] com.netflix.discovery.DiscoveryClient    : Unregistering ...
2021-06-21 00:18:22.215  INFO 18252 --- [       Thread-6] com.netflix.discovery.DiscoveryClient    : DiscoveryClient_SKILLTECHNOLOGIESSERVICE/LOCALHOST:skillTechnologiesService:8940 - deregister  status: 200
2021-06-21 00:18:22.239  INFO 18252 --- [       Thread-6] com.netflix.discovery.DiscoveryClient    : Completed shut down of DiscoveryClient
Terminate batch job (Y/N)? Y

D:\development\spring-boot-api-gateway-zuul\spring-boot-zuul-gateway-proxy-skillstechnologies-service>

Test /student/getStudentDetails microservice

http://localhost:8989/portal/student/getStudentDetails/The%20Basic%20Tech%20Info

Here is the fall back output in the browser.

Test /student/getStudentDetails microservice
2021-06-21 00:07:59.750  INFO 14940 --- [  restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8930 (http) with context path ''
2021-06-21 00:07:59.751  INFO 14940 --- [  restartedMain] .s.c.n.e.s.EurekaAutoServiceRegistration : Updating port to 8930
2021-06-21 00:07:59.765  INFO 14940 --- [  restartedMain] c.t.b.t.i.s.StudentServiceApp            : Started StudentServiceApp in 27.7 seconds (JVM running for 29.519)
2021-06-21 00:08:57.988  INFO 14940 --- [nio-8930-exec-2] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
2021-06-21 00:08:57.989  INFO 14940 --- [nio-8930-exec-2] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2021-06-21 00:08:58.086  INFO 14940 --- [nio-8930-exec-2] o.s.web.servlet.DispatcherServlet        : Completed initialization in 88 ms
2021-06-21 00:08:58.318  INFO 14940 --- [nio-8930-exec-2] c.t.b.t.i.s.StudentServiceApp            : Going to call skillstechnologies /getStudentCourse/ service (Hystrix Enabled) to get data!
2021-06-21 00:08:59.159  INFO 14940 --- [rviceDelegate-1] c.t.b.t.i.s.d.StudentServiceDelegate     : Getting StudentSubject details for The Basic Tech Info
2021-06-21 00:09:01.003  INFO 14940 --- [rviceDelegate-1] c.t.b.t.i.s.d.StudentServiceDelegate     : Response Received as MBA -  Mon Jun 21 00:09:01 IST 2021
2021-06-21 00:09:01.052  INFO 14940 --- [nio-8930-exec-2] c.t.b.t.i.s.StudentServiceApp            : course/class value from skillstechnologies microservice NORMAL FLOW. Student Course: MBA
2021-06-21 00:09:06.182  INFO 14940 --- [nio-8930-exec-3] c.t.b.t.i.s.StudentServiceApp            : Going to call skillstechnologies /getStudentCourse/ service (Hystrix Enabled) to get data!
2021-06-21 00:09:06.188  INFO 14940 --- [rviceDelegate-2] c.t.b.t.i.s.d.StudentServiceDelegate     : Getting StudentSubject details for The Basic Tech Info
2021-06-21 00:09:06.234  INFO 14940 --- [rviceDelegate-2] c.t.b.t.i.s.d.StudentServiceDelegate     : Response Received as MBA -  Mon Jun 21 00:09:06 IST 2021
2021-06-21 00:09:06.237  INFO 14940 --- [nio-8930-exec-3] c.t.b.t.i.s.StudentServiceApp            : course/class value from skillstechnologies microservice NORMAL FLOW. Student Course: MBA
2021-06-21 00:12:59.020  INFO 14940 --- [trap-executor-0] c.n.d.s.r.aws.ConfigClusterResolver      : Resolving eureka endpoints via configuration
2021-06-21 00:17:59.023  INFO 14940 --- [trap-executor-0] c.n.d.s.r.aws.ConfigClusterResolver      : Resolving eureka endpoints via configuration
2021-06-21 00:19:36.277  INFO 14940 --- [nio-8930-exec-5] c.t.b.t.i.s.StudentServiceApp            : Going to call skillstechnologies /getStudentCourse/ service (Hystrix Enabled) to get data!
2021-06-21 00:19:36.312  INFO 14940 --- [rviceDelegate-3] c.t.b.t.i.s.d.StudentServiceDelegate     : Getting StudentSubject details for The Basic Tech Info
2021-06-21 00:19:36.490  INFO 14940 --- [rviceDelegate-3] c.t.b.t.i.s.d.StudentServiceDelegate     : Skills Tech Service is down!!! Hystrix fallback route enabled for this service.
2021-06-21 00:19:36.502  INFO 14940 --- [nio-8930-exec-5] c.t.b.t.i.s.StudentServiceApp            : course/class value from skillstechnologies microservice CIRCUIT BREAKER ENABLED. No Response From Skills Tech Service at this moment. Service will be back Shortly.

Hystrix: CIRCUIT OPEN State to CLOSED State

Suppose skillstechnologies microservice is up now. Just start the microservice again and see the result.

Test /student/getStudentDetails microservice

http://localhost:8989/portal/student/getStudentDetails/The%20Basic%20Tech%20Info

2021-06-21 00:27:39.573  INFO 11328 --- [           main] c.n.c.sources.URLConfigurationSource     : To enable URLs as dynamic configuration sources, define System property archaius.configurationSource.additionalUrls or make config.properties available on classpath.
2021-06-21 00:27:39.589  WARN 11328 --- [           main] c.n.c.sources.URLConfigurationSource     : No URLs will be polled as dynamic configuration sources.
2021-06-21 00:27:39.592  INFO 11328 --- [           main] c.n.c.sources.URLConfigurationSource     : To enable URLs as dynamic configuration sources, define System property archaius.configurationSource.additionalUrls or make config.properties available on classpath.
2021-06-21 00:27:39.918  INFO 11328 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
2021-06-21 00:27:43.535  INFO 11328 --- [           main] o.s.c.n.eureka.InstanceInfoFactory       : Setting initial instance status as: STARTING
2021-06-21 00:27:43.651  INFO 11328 --- [           main] com.netflix.discovery.DiscoveryClient    : Initializing Eureka in region us-east-1
2021-06-21 00:27:44.022  INFO 11328 --- [           main] c.n.d.provider.DiscoveryJerseyProvider   : Using JSON encoding codec LegacyJacksonJson
2021-06-21 00:27:44.023  INFO 11328 --- [           main] c.n.d.provider.DiscoveryJerseyProvider   : Using JSON decoding codec LegacyJacksonJson
2021-06-21 00:27:44.332  INFO 11328 --- [           main] c.n.d.provider.DiscoveryJerseyProvider   : Using XML encoding codec XStreamXml
2021-06-21 00:27:44.333  INFO 11328 --- [           main] c.n.d.provider.DiscoveryJerseyProvider   : Using XML decoding codec XStreamXml
2021-06-21 00:27:44.760  INFO 11328 --- [           main] c.n.d.s.r.aws.ConfigClusterResolver      : Resolving eureka endpoints via configuration
2021-06-21 00:27:46.191  INFO 11328 --- [           main] com.netflix.discovery.DiscoveryClient    : Disable delta property : false
2021-06-21 00:27:46.198  INFO 11328 --- [           main] com.netflix.discovery.DiscoveryClient    : Single vip registry refresh property : null
2021-06-21 00:27:46.200  INFO 11328 --- [           main] com.netflix.discovery.DiscoveryClient    : Force full registry fetch : false
2021-06-21 00:27:46.206  INFO 11328 --- [           main] com.netflix.discovery.DiscoveryClient    : Application is null : false
2021-06-21 00:27:46.211  INFO 11328 --- [           main] com.netflix.discovery.DiscoveryClient    : Registered Applications size is zero : true
2021-06-21 00:27:46.218  INFO 11328 --- [           main] com.netflix.discovery.DiscoveryClient    : Application version is -1: true
2021-06-21 00:27:46.220  INFO 11328 --- [           main] com.netflix.discovery.DiscoveryClient    : Getting all instance registry info from the eureka server
2021-06-21 00:27:47.203  INFO 11328 --- [           main] com.netflix.discovery.DiscoveryClient    : The response status is 200
2021-06-21 00:27:47.211  INFO 11328 --- [           main] com.netflix.discovery.DiscoveryClient    : Starting heartbeat executor: renew interval is: 30
2021-06-21 00:27:47.225  INFO 11328 --- [           main] c.n.discovery.InstanceInfoReplicator     : InstanceInfoReplicator onDemand update allowed rate per min is 4
2021-06-21 00:27:47.235  INFO 11328 --- [           main] com.netflix.discovery.DiscoveryClient    : Discovery Client initialized at timestamp 1624215467233 with initial instances count: 2
2021-06-21 00:27:47.240  INFO 11328 --- [           main] o.s.c.n.e.s.EurekaServiceRegistry        : Registering application SKILLTECHNOLOGIESSERVICE with eureka with status UP
2021-06-21 00:27:47.249  INFO 11328 --- [           main] com.netflix.discovery.DiscoveryClient    : Saw local status change event StatusChangeEvent [timestamp=1624215467249, current=UP, previous=STARTING]
2021-06-21 00:27:47.269  INFO 11328 --- [nfoReplicator-0] com.netflix.discovery.DiscoveryClient    : DiscoveryClient_SKILLTECHNOLOGIESSERVICE/LOCALHOST:skillTechnologiesService:8940: registering service...
2021-06-21 00:27:47.391  INFO 11328 --- [nfoReplicator-0] com.netflix.discovery.DiscoveryClient    : DiscoveryClient_SKILLTECHNOLOGIESSERVICE/LOCALHOST:skillTechnologiesService:8940 - registration status: 204
2021-06-21 00:27:47.441  INFO 11328 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8940 (http) with context path ''
2021-06-21 00:27:47.445  INFO 11328 --- [           main] .s.c.n.e.s.EurekaAutoServiceRegistration : Updating port to 8940
2021-06-21 00:27:47.450  INFO 11328 --- [           main] .t.b.t.i.s.SkillsTechnologiesApplication : Started SkillsTechnologiesApplication in 14.529 seconds (JVM running for 23.448)

How to open Hystrix Dashboard

In Spring Boot 2.x, the hystrix.stream endpoint has been moved to /actuator/hystrix.stream. And, this actuator endpoint enabled via following property (in application.yaml file of spring-boot-zuul-gateway-proxy-student-service microservice).

management.endpoints.web.exposure.include=hystrix.stream

Give below URL in Browser: http://localhost:8930/hystrix

hystrix.stream dashboard

Then give below URL in text box in form: http://localhost:8930/actuator/hystrix.stream

hystrix.stream dashboard

Turbine

Instead of having a separate dashboard for every service we can use Turbine to provide a unified view of all services in a single dashboard.

Turbine provides a way to aggregate this information across all installations of an application in a cluster. Integrating turbine into a Spring-Cloud based application is straightforward, all it requires is information on which clusters to expose information on and how to aggregate information about the specific clusters. 

Below maven dependency needs to be added in pom.xml file

<dependency>
 <groupId>org.springframework.cloud</groupId>
 <artifactId>spring-cloud-starter-turbine</artifactId>
 <exclusions>
  <exclusion>
   <groupId>javax.servlet</groupId>
   <artifactId>servlet-api</artifactId>
   </exclusion>
 </exclusions>
</dependency>

Download Source Code (Attached)

Happy learning. Have a great day 🙂