Hystrix Dashboard provides benefits to monitoring the set of metrics on a dashboard. It displays the health of each circuit-breaker in a very simple way.. In this tutorial we will learn how to use it in a Spring Boot project.
Setting up your Spring Boot project
Firstly, bootstrap your project, including the following dependencies:
spring init -dweb,cloud-hystrix,cloud-hystrix-dashboard,actuator hystrix-dashboard
Next, open your project “hystrix-dashboard” in your favourite IDE. Here is the list of dependencies that you will find:
<?xml version="1.0" encoding="UTF-8"?><project> <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.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> </project>
Next, let’s code the classes. Firstly, we will add the Main Application class:
package com.example.demohystrix; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.hystrix.EnableHystrix; import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard; @EnableHystrix @EnableHystrixDashboard @SpringBootApplication public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } }
- The @EnableHystrix enables Hystrix capabilities in your Spring Boot application.
- The @EnableHystrixDashboard will give a dashboard view of Hystrix stream.
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 = "/hello") @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.
Next, let’s configure the endpoint stream exposure in application.properties:
management.endpoint.health.enabled=true management.endpoints.jmx.exposure.include=* management.endpoints.web.exposure.include=* management.endpoints.web.base-path=/actuator management.endpoints.web.cors.allowed-origins=true management.endpoint.health.show-details=always
Finally, build and start your application:
$ mvn clean install $ java -jar java -jar target/demo-hystrix-0.0.1-SNAPSHOT.jar
Now let’s issue some requests to the available endpoint (“/hello”) and then check that the actuator stream has collected metrics. The actuator stream is available at: http://localhost:8080/actuator/hystrix.stream
$ curl http://localhost:8080/actuator/hystrix.stream ping: data: {"type":"HystrixCommand","name":"hello","group":"SampleController","currentTime":1565792616119,"isCircuitBreakerOpen":false,"errorPercentage":0,"errorCount":0,"requestCount":0,"rollingCountBadRequests":0,"rollingCountCollapsedRequests":0,"rollingCountEmit":0,"rollingCountExceptionsThrown":0,"rollingCountFailure":0,"rollingCountFallbackEmit":0,"rollingCountFallbackFailure":0,"rollingCountFallbackMissing":0,"rollingCountFallbackRejection":0,"rollingCountFallbackSuccess":0,"rollingCountResponsesFromCache":0,"rollingCountSemaphoreRejected":0,"rollingCountShortCircuited":0,"rollingCountSuccess":0,"rollingCountThreadPoolRejected":0,"rollingCountTimeout":0,"currentConcurrentExecutionCount":0,"rollingMaxConcurrentExecutionCount":0,"latencyExecute_mean":0,"latencyExecute":{"0":0,"25":0,"50":0,"75":0,"90":0,"95":0,"99":0,"99.5":0,"100":0},"latencyTotal_mean":0,"latencyTotal":{"0":0,"25":0,"50":0,"75":0,"90":0,"95":0,"99":0,"99.5":0,"100":0},"propertyValue_circuitBreakerRequestVolumeThreshold":20,"propertyValue_circuitBreakerSleepWindowInMilliseconds":5000,"propertyValue_circuitBreakerErrorThresholdPercentage":50,"propertyValue_circuitBreakerForceOpen":false,"propertyValue_circuitBreakerForceClosed":false,"propertyValue_circuitBreakerEnabled":true,"propertyValue_executionIsolationStrategy":"THREAD","propertyValue_executionIsolationThreadTimeoutInMilliseconds":1000,"propertyValue_executionTimeoutInMilliseconds":1000,"propertyValue_executionIsolationThreadInterruptOnTimeout":true,"propertyValue_executionIsolationThreadPoolKeyOverride":null,"propertyValue_executionIsolationSemaphoreMaxConcurrentRequests":10,"propertyValue_fallbackIsolationSemaphoreMaxConcurrentRequests":10,"propertyValue_metricsRollingStatisticalWindowInMilliseconds":10000,"propertyValue_requestCacheEnabled":true,"propertyValue_requestLogEnabled":true,"reportingHosts":1,"threadPool":"SampleController"} data: {"type":"HystrixThreadPool","name":"SampleController","currentTime":1565792616119,"currentActiveCount":0,"currentCompletedTaskCount":2,"currentCorePoolSize":10,"currentLargestPoolSize":2,"currentMaximumPoolSize":10,"currentPoolSize":2,"currentQueueSize":0,"currentTaskCount":2,"rollingCountThreadsExecuted":0,"rollingMaxActiveThreads":0,"rollingCountCommandRejections":0,"propertyValue_queueSizeRejectionThreshold":5,"propertyValue_metricsRollingStatisticalWindowInMilliseconds":10000,"reportingHosts":1}
Now that we the stream is available and some requests have been recorded, let’s get into the Hystrix Dashboard which is available at: http://localhost:8080/hystrix
Copy the hystrix stream in it (http://localhost:8080/actuator/hystrix.stream) then click on “Monitor Stream” to get a meaningful dynamic visual representation of the circuit being monitored by the Hystrix component.
Source code
The source code for the Hystrix Dashboard example is available at: https://github.com/fmarchioni/masterspringboot/tree/master/hystrix/hystrix-dashboard