我们提到断路器是根据一段时间窗内的请求情况来判断并操作断路器的打开和关闭状态的。而这些请求情况的指标信息都是HystrixCommand和HystrixObservableCommand实例在执行过程中记录的重要度量信息,它们除了Hystrix断路器实现中使用之外,对于系统运维也有非常大的帮助。这些指标信息会以“滚动时间窗”与“桶”结合的方式进行汇总,并在内存中驻留一段时间,以供内部或外部进行查询使用,Hystrix Dashboard就是这些指标内容的消费者之一。
下面我们基于之前的示例来结合Hystrix Dashboard实现Hystrix指标数据的可视化面板,这里我们将用到下之前实现的几个应用,包括:
-
eureka-server:服务注册中心
-
eureka-client:服务提供者
-
eureka-consumer-ribbon-hystrix:使用ribbon和hystrix实现的服务消费者
由于eureka-consumer-ribbon-hystrix项目中的/consumer
接口实现使用了@HystrixCommand
修饰,所以这个接口的调用情况会被Hystrix记录下来,以用来给断路器和Hystrix Dashboard使用。断路器我们在上一篇中已经介绍过了,下面我们来具体说说Hystrix Dashboard的构建。
动手试一试
在Spring Cloud中构建一个Hystrix Dashboard非常简单,只需要下面四步:
-
创建一个标准的Spring Boot工程,命名为:hystrix-dashboard。
-
编辑pom.xml,具体依赖内容如下:
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-parent</artifactId>
<version>Dalston.SR1</version>
<relativePath />
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
-
为应用主类加上
@EnableHystrixDashboard
,启用Hystrix Dashboard功能。
@EnableHystrixDashboard
@SpringCloudApplication
public class HystrixDashboardApplication {
public static void main(String[] args) {
SpringApplication.run(HystrixDashboardApplication.class, args);
}
}
-
根据实际情况修改
application.properties
配置文件,比如:选择一个未被占用的端口等,此步非必须。
spring.application.name=hystrix-dashboard
server.port=1301
到这里我们已经完成了基本配置,接下来我们可以启动该应用,并访问:http://localhost:1301/hystrix
,我们可以看到如下页面:
这是Hystrix Dashboard的监控首页,该页面中并没有具体的监控信息。从页面的文字内容中我们可以知道,Hystrix Dashboard共支持三种不同的监控方式,依次为:
-
默认的集群监控:通过URL
http://turbine-hostname:port/turbine.stream
开启,实现对默认集群的监控。 -
指定的集群监控:通过URL
http://turbine-hostname:port/turbine.stream?cluster=[clusterName]
开启,实现对clusterName集群的监控。 -
单体应用的监控:通过URL
http://hystrix-app:port/hystrix.stream
开启,实现对具体某个服务实例的监控。
前两者都对集群的监控,需要整合Turbine才能实现,这部分内容我们将在下一篇中做详细介绍。在本节中,我们主要实现对单个服务实例的监控,所以这里我们先来实现单个服务实例的监控。
既然Hystrix Dashboard监控单实例节点需要通过访问实例的/hystrix.stream
接口来实现,自然我们需要为服务实例添加这个端点,而添加该功能的步骤也同样简单,只需要下面两步:
-
在服务实例
pom.xml
中的dependencies
节点中新增spring-boot-starter-actuator
监控模块以开启监控相关的端点,并确保已经引入断路器的依赖spring-cloud-starter-hystrix
:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
-
确保在服务实例的主类中已经使用
@EnableCircuitBreaker
或@EnableHystrix
注解,开启了断路器功能。
到这里已经完成了所有的配置,我们可以在Hystrix Dashboard的首页输入http://localhost:2101/hystrix.stream
,已启动对“eureka-consumer-ribbon-hystrix”的监控,点击“Monitor Stream”按钮,此时我们可以看到如下页面:
在对该页面介绍前,我们先看看在首页中我们还没有介绍的两外两个参数:
-
Delay
:该参数用来控制服务器上轮询监控信息的延迟时间,默认为2000毫秒,我们可以通过配置该属性来降低客户端的网络和CPU消耗。 -
Title
:该参数对应了上图头部标题Hystrix Stream之后的内容,默认会使用具体监控实例的URL,我们可以通过配置该信息来展示更合适的标题。
回到监控页面,我们来详细说说其中各元素的具体含义:
-
我们可以在监控信息的左上部分找到两个重要的图形信息:一个实心圆和一条曲线。
-
实心圆:共有两种含义。它通过颜色的变化代表了实例的健康程度,如下图所示,它的健康度从绿色、黄色、橙色、红色递减。该实心圆除了颜色的变化之外,它的大小也会根据实例的请求流量发生变化,流量越大该实心圆就越大。所以通过该实心圆的展示,我们就可以在大量的实例中快速的发现故障实例和高压力实例。
-
曲线:用来记录2分钟内流量的相对变化,我们可以通过它来观察到流量的上升和下降趋势。
-
-
其他一些数量指标如下图所示:
2. 利用Turbine在一个Dashboard上监控多个流
以上例子只能监控一个,要同时监控多个流怎么办? 答案是, 可以单独做一个Turbine服务,专门监控所有断路器状态,从而掌握整个系统中所有微服务的状态。下面我们就来创建一个Turbine服务,来监控我们之前做的Feign服务和Ribbon服务
1). 创建一个maven工程, 在pox.xml添加以下依赖
1 <dependency>
2 <groupId>org.springframework.cloud</groupId>
3 <artifactId>spring-cloud-starter-turbine</artifactId>
4 </dependency>
5 <dependency>
6 <groupId>org.springframework.cloud</groupId>
7 <artifactId>spring-cloud-netflix-turbine</artifactId>
8 </dependency>
9 <dependency>
10 <groupId>org.springframework.boot</groupId>
11 <artifactId>spring-boot-starter-actuator</artifactId>
12 </dependency>
13 <dependency>
14 <groupId>org.springframework.cloud</groupId>
15 <artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
16 </dependency>
整个个pox.xml文件如下:
1 <?xml version="1.0" encoding="UTF-8"?>
2 <project xmlns="http://maven.apache.org/POM/4.0.0"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5 <modelVersion>4.0.0</modelVersion>
6 <groupId>cm.chry</groupId>
7 <artifactId>spring.helloworld.turbine.service</artifactId>
8 <version>0.0.1-SNAPSHOT</version>
9 <name>spring.helloworld.turbine.service</name>
10 <description>Turbine service demo</description>
11 <parent>
12 <groupId>org.springframework.boot</groupId>
13 <artifactId>spring-boot-starter-parent</artifactId>
14 <version>1.5.3.RELEASE</version>
15 <relativePath/> <!-- lookup parent from repository -->
16 </parent>
17
18 <properties>
19 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
20 <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
21 <java.version>1.8</java.version>
22 </properties>
23
24 <dependencies>
25 <dependency>
26 <groupId>org.springframework.cloud</groupId>
27 <artifactId>spring-cloud-starter-eureka</artifactId>
28 </dependency>
29 <dependency>
30 <groupId>org.springframework.boot</groupId>
31 <artifactId>spring-boot-starter-web</artifactId>
32 </dependency>
33 <dependency>
34 <groupId>org.springframework.cloud</groupId>
35 <artifactId>spring-cloud-starter-turbine</artifactId>
36 </dependency>
37 <dependency>
38 <groupId>org.springframework.cloud</groupId>
39 <artifactId>spring-cloud-netflix-turbine</artifactId>
40 </dependency>
41 <dependency>
42 <groupId>org.springframework.boot</groupId>
43 <artifactId>spring-boot-starter-actuator</artifactId>
44 </dependency>
45 <dependency>
46 <groupId>org.springframework.cloud</groupId>
47 <artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
48 </dependency>
49 <dependency>
50 <groupId>org.springframework.boot</groupId>
51 <artifactId>spring-boot-starter-test</artifactId>
52 <scope>test</scope>
53 </dependency>
54 </dependencies>
55
56 <dependencyManagement>
57 <dependencies>
58 <dependency>
59 <groupId>org.springframework.cloud</groupId>
60 <artifactId>spring-cloud-dependencies</artifactId>
61 <version>Dalston.RC1</version>
62 <type>pom</type>
63 <scope>import</scope>
64 </dependency>
65 </dependencies>
66 </dependencyManagement>
67
68 <build>
69 <plugins>
70 <plugin>
71 <groupId>org.springframework.boot</groupId>
72 <artifactId>spring-boot-maven-plugin</artifactId>
73 </plugin>
74 </plugins>
75 </build>
76
77 <repositories>
78 <repository>
79 <id>spring-milestones</id>
80 <name>Spring Milestones</name>
81 <url>https://repo.spring.io/milestone</url>
82 <snapshots>
83 <enabled>false</enabled>
84 </snapshots>
85 </repository>
86 </repositories>
87 </project>
2). 创建Turbine Dashboard启动类:
用@EnableHystrixDashboard和@EnableTurbine修饰主类, 分别用于支持Hystrix Dashboard和Turbine
1 package spring.helloworld.turbine.service;
2
3 import org.springframework.boot.SpringApplication;
4 import org.springframework.boot.autoconfigure.SpringBootApplication;
5 import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;
6 import org.springframework.cloud.netflix.turbine.EnableTurbine;
7
8 @SpringBootApplication
9 @EnableHystrixDashboard
10 @EnableTurbine
11 public class DashboardApplication {
12
13 public static void main(String[] args) {
14 SpringApplication.run(DashboardApplication.class, args);
15 }
16 }
3). 在application.yml中配置turbine参数
1 eureka:
2 client:
3 serviceUrl:
4 defaultZone: http://localhost:8761/eureka/
5 server:
6 port: 8903
7 spring:
8 application:
9 name: hystrix-dashboard-turbine
10 turbine:
11 appConfig: service-feign, service-ribbon
12 aggregator:
13 clusterConfig: default
14 clusterNameExpression: new String("default")
turbine.appConfig定义了要监控的服务,这里是我们在前面章节创建的service-feign和sercice-ribbon; aggregator.clusterConfig定义了聚合方式, 此处为default.
turbine.appConfig
:配置Eureka中的serviceId列表,表明监控哪些服务
turbine.aggregator.clusterConfig
:指定聚合哪些集群,多个使用”,”分割,默认为default。可使用http://.../turbine.stream?cluster={clusterConfig之一}
访问
turbine.clusterNameExpression
:指定集群名称,可以是三种类型的值
- 默认表达式为appName;此时turbine.aggregator.clusterConfig
需要配置想要监控的应用名称;
- 当为default时,turbine.aggregator.clusterConfig
可以不写,因为默认就是default;
- 当为metadata[‘cluster’]时,假设想要监控的应用配置了eureka.instance.metadata-map.cluster: ABC
,则需要配置,同时turbine.aggregator.clusterConfig: ABC
4). 依次启动eureka服务, 2个Helloworld服务, Feign服务,ribbon服务和刚创建turbine服务。从eureka服务中我们可以看到
5)通过Turbine服务访问HystrixDashborad, http:localhost:8903/hystrix
监控流的URL填http://localhost:8903/turbine.stream, 点击monitor stream, 进入监控页面, 随便刷新下feign和ribbon服务(http://localhost:8902/hello和http://localhost:8901), 可以看到监控页面的变化。如下图, 两个服务的监控都会显示在dashboard上