Hystrix Dashboard 介绍
首先我们要明确Hystrix Dashboard是两个概念:Hystrix和Dashboard。
1.Hystrix:SpringCloud中的Hystrix组件,也就是断路器,可以实现服务降级的功能。
定义的服务如果发生错误就可以使用Hystrix定义错误之后的回退。
通常在工程中使用HystrixCommand注解实现,该注解源码如下:
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface HystrixCommand {
String groupKey() default "";
String commandKey() default "";
String threadPoolKey() default "";
String fallbackMethod() default "";
HystrixProperty[] commandProperties() default {};
HystrixProperty[] threadPoolProperties() default {};
Class<? extends Throwable>[] ignoreExceptions() default {};
ObservableExecutionMode observableExecutionMode() default ObservableExecutionMode.EAGER;
HystrixException[] raiseHystrixExceptions() default {};
String defaultFallback() default "";
}
通过@Target({ElementType.METHOD})我们可以知道这个注解是定义在方法上的。其中比较重要的方法是String fallbackMethod() default ""; 它是定义回退方法的名称,这个方法必须和Hystrix执行方法在相同的类中。
以下是一个具体使用的例子:
public SearchResponse fallback(SearchRequest request, Throwable e){
return null;
}
@Override
@HystrixCommand(fallbackMethod = "fallback")
public SearchResponse fetchAds(SearchRequest request) {
...
}
这样当fetchAds方法抛出异常时就会调用fallback方法。
但这是怎么实现的呢?
这是通过在应用启动类中定义的@EnableCircuitBreaker来实现的,这个注解会通过AOP去拦截所有的HystrixCommand方法,从而时HystrixCommand能够集成到SpringBoot中,并且将注解方法扔到Hystrix的线程池中,发生失败时通过反射去调用回退方法实现断路。
结合上面的例子来说就是@EnableCircuitBreaker将@HystrixCommand定义的fetchAds方法扔到Hystrix自己的线程池里面然后通过try-catch-finally把它包装起来,如果发生失败就在catch或者finally里通过反射调用fallback方法。
2.Dashboard
在上段描述的过程发生的同时Hystrix会在线程池中记录它的内存,会在内存中记录一些执行信息,所以我们可以有一个服务或工具去读取这些数据以仪表盘的形式展示这些信息,比如:成功调用的次数、失败调用的次数、服务频率等。这就是Dashboard。
同时我们需要知道@HystrixCommand需要将指定方法抛到Hystrix自己的线程池里,而且一旦失败又会通过反射调用fallbackmethod,而Java中的反射本身效率就非常低,所以它的总体效率的非常低的,因此@HystrixCommand在实际的企业级开发中使用频率并不高。
我们在使用Hystrix的时候大部分情况下都是与Feign结合使用 ,如:
@FeignClient(value = "eureka-client-ad-sponsor",
fallback = SponsorClientHystrix.class)
public interface SponsorClient {
@RequestMapping(value = "/ad-sponsor/get/adPlan", method = RequestMethod.POST)
CommonResponse<List<AdPlan>> getAdPlans(
@RequestBody AdPlanGetRequest request);
}
单独使用@HystrixCommand的情况是比较少的。
接下来我们去实现一个监控Hystrix执行信息的Dashboard模块。
Dashboard模块的实现
由于SpringCloud已经帮我们封装好了Dashboard,所以我们只需要做很少的工作就可以完成Dashboard的搭建。
以下代码以我的广告系统为例
项目源码地址:https://github.com/leonnor/lining-ad-spring-cloud
首先在service模块下创建一个dashboard模块(maven项目)
编写pom文件
<?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">
<parent>
<artifactId>lining-ad-service</artifactId>
<groupId>com.lining.ad</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>ad-dashboard</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<dependencies>
<!-- 引入服务容错 Hystrix 的依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<!-- Hystrix 监控 -->
<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>
<!--
Eureka 客户端, 客户端向 Eureka Server 注册的时候会提供一系列的元数据信息, 例如: 主机, 端口, 健康检查url等
Eureka Server 接受每个客户端发送的心跳信息, 如果在某个配置的超时时间内未接收到心跳信息, 实例会被从注册列表中移除
-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
<!--
SpringBoot的Maven插件, 能够以Maven的方式为应用提供SpringBoot的支持,可以将
SpringBoot应用打包为可执行的jar或war文件, 然后以通常的方式运行SpringBoot应用
-->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
编写资源配置文件(这里使用yml格式)
server:
port: 7002
spring:
application:
name: ad-dashboard
eureka:
client:
service-url:
defaultZone: http://server1:8000/eureka/
management:
endpoints:
web:
exposure:
include: "*"
编写启动程序
package com.lining.ad;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;
/**
* className DashboardApplication
* description TODO
*
* @author ln
* @version 1.0
* @date 2019/4/27 13:52
*/
@EnableEurekaClient
@SpringBootApplication
@EnableHystrixDashboard
public class DashboardApplication {
public static void main(String[] args) {
SpringApplication.run(DashboardApplication.class, args);
}
}
至此我们的Dashboard模块已经完成了,剩下的工作就是由SpringCloud的Dashboard组件帮我们去完成的。我们运行这里的main函数就可以ad-dashboard注册到eurekaserver上启动监控。
Dashboard的具体监控页面的介绍我会在项目测试时在此更新。