Spring Cloud -Hoxton.RELEASE(九):监控中心-HystrixDashboard+Turbine

Hystrix Dashboard

Hystrix Dashboard的Github README对Hystrix Dashboard描述如下:

This is a dashboard for monitoring applications using Hystrix.

这是一个使用Hystrix监控应用程序的仪表板。

简单来讲就是监控仪表盘

创建Hystrix Dashboard项目

创建hystrix-dashboard项目依赖继承monitor-center项目,pom.xml文件如下:

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.github.liuzhuoming23</groupId>
<artifactId>monitor-center</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<packaging>jar</packaging>

<artifactId>hystrix-dashboard</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>hystrix-dashboard</name>
<description>Demo project for Spring Cloud</description>

<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-dashboard</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-security</artifactId>
</dependency>

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

application.yml配置为:

server:
port: 8070

spring:
application:
name: @pom.artifactId@
security:
user:
name: 'admin'
password: 'admin'

修改启动类HystrixDashboardApplication为:

package com.github.liuzhuoming23.hystrixdashboard;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;

/**
* 启动类
*
* @author x-047
*/
@SpringBootApplication
@EnableHystrixDashboard
public class HystrixDashboardApplication {

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

}

之后启动hystrix-dashboard项目。
Hystrix Dashboard顾名思义和Hystrix有关,即监控的项目中必须启用了Hystrix作为熔断,通过Hystrix收集并发送数据流,在本次示例里面只有feign项目符合条件。

修改feign项目

修改feign项目application.yml,在actuator配置添加hystrix.stream endpoint:

server:
port: 8020

spring:
application:
name: @pom.artifactId@
sleuth:
web:
client:
enabled: true
sampler:
probability: 1.0
zipkin:
base-url: http://localhost:9411/
locator:
discovery:
enabled: true
sender:
type: rabbit
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest

eureka:
client:
service-url:
defaultZone: http://admin:admin@localhost:8000/eureka/

feign:
hystrix:
enabled: true

management:
endpoints:
web:
exposure:
include: httptrace,info,health,hystrix.stream

之后重启feign项目,并访问http://localhost:8070/hystrix,返回如下页面:
01.jpg
在上面的输入框里输入http://localhost:8020/actuator/hystrix.stream,并点击Monitor Stream按钮,会跳转到Hystrix Monitor页面:
02.jpg
有时候跳转之后页面显示为loading是因为被监控项目没有接收到请求的原因,手动请求一次就有显示了。
用Postman多次请求http://localhost:8030/feign/port/🐕,然后会发现Hystrix Monitor已经显示出了请求的信息:
03.jpg
如果不明白仪表盘的哪个数值代表的含义,可以把光标放到对应的数值上面,就会显示出对应的描述。

Turbine

Hystrix Dashboard虽然表示的数值挺直观,但是一次只能监控一个服务的其中一个实例,不是很方便,需要和Turbine配合才能完成对多个服务的多个实例的监控。

Turbine的Github Wiki对Turbine描述如下:

Turbine is a tool for aggregating streams of Server-Sent Event (SSE) JSON data into a single stream. The targeted use case is metrics streams from instances in an SOA being aggregated for dashboards.

Turbine是一种将服务器发送事件(SSE)JSON数据流聚合到单个流中的工具。目标用例是来自正在为仪表板聚合的SOA中的实例的度量标准流。

简单来讲就是数据流聚合

创建Turbine项目

创建turbine项目依赖继承monitor-center项目,pom.xml文件如下:

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.github.liuzhuoming23</groupId>
<artifactId>monitor-center</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<packaging>jar</packaging>

<artifactId>turbine</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>turbine</name>
<description>Demo project for Spring Cloud</description>

<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Hoxton.RELEASE</spring-cloud.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-turbine</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>

配置application.yml为:

server:
port: 8090

spring:
application:
name: @pom.artifactId@

management:
endpoints:
web:
exposure:
include: info,health

turbine:
#需要监控的集群名称表达式
clusterNameExpression: new String("default")
aggregator:
#需要监控的集群设置
clusterConfig: default
#需要监控的服务名称
appConfig: feign

eureka:
client:
service-url:
defaultZone: http://admin:admin@localhost:8000/eureka/

修改启动类为:

package com.github.liuzhuoming23.turbine;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.turbine.EnableTurbine;

/**
* 启动类
*
* @author x-047
*/
@SpringBootApplication
@EnableTurbine
public class TurbineApplication {

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

}

启动项目,并再次访问http://localhost:8070/hystrix,在输入框输入http://localhost:8090/turbine.stream并点击Monitor Stream按钮,会跳转到Hystrix Monitor页面:
04.jpg
可以看到host表示的数值已经不是1了,具体数值跟启动的feign实例数量相同,比如我启动了两个feign,在这里就显示2。
证明可以成功聚合数据流。

多服务数据流的聚合很简单,请自行尝试。

通过RabbitMQ中转Hystrix数据流到Turbine

此时我们遇到了和搭建Zipkin时候类似的问题——服务过于耦合,Turbine直接从注册中心接受各个服务传来的数据流,会给注册中心增加很大的负载,所以同样我们可以使用RabbitMQ来中转Hystrix数据流来解耦。
首先修改feign项目的pom.xml:

<?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>
<parent>
<groupId>com.github.liuzhuoming23</groupId>
<artifactId>route-center</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<packaging>jar</packaging>

<artifactId>feign</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>feign</name>
<description>Demo project for Spring Cloud</description>

<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-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</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-sleuth</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-stream-rabbit</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix-hystrix-stream</artifactId>
</dependency>

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

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

</project>

然后重启feign项目。
之后修改turbine项目的pom.xml为:

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.github.liuzhuoming23</groupId>
<artifactId>monitor-center</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<packaging>jar</packaging>

<artifactId>turbine</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>turbine</name>
<description>Demo project for Spring Cloud</description>

<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Hoxton.RELEASE</spring-cloud.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-turbine-stream</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-stream-rabbit</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix-hystrix-stream</artifactId>
</dependency>

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

application.yml修改为:

server:
port: 8090

spring:
application:
name: @pom.artifactId@
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest

management:
endpoints:
web:
exposure:
include: info,health

eureka:
client:
service-url:
defaultZone: http://admin:admin@localhost:8000/eureka/

启动类修改为:

package com.github.liuzhuoming23.turbine;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.turbine.stream.EnableTurbineStream;

/**
* 启动类
*
* @author x-047
*/
@SpringBootApplication
@EnableTurbineStream
public class TurbineApplication {

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

}

然后重启turbine项目。
接着访问RabbitMQ管理页面的Exchanges选项卡,http://localhost:15672/#/exchanges
06.jpg
会看到已经生成了两个新的Exchange,hystrixStreamOutput(Hystrix发送数据流交换器),turbineStreamInput(Turbine接收数据交换器),再打开Queues选项卡:
07.jpg
会发现已经生成了一个新的Queue,turbineStreamInput(Turbine消息队列)。
但是当我们访问http://localhost:8070/hystrix,在输入框输入http://localhost:8090/turbine.stream并点击Monitor Stream按钮,跳转到Hystrix Monitor页面之后却发现并没有获取到数据,即使多次使用Postman请求也没用。打开Exchanges选项卡的hystrixStreamOutput详情页之后可以看到:
08.jpg
只有Publish(In)没有Publish(Out),即消息在正确的产生却并没有被消费掉,点开Bindings按钮,可以看到下面列表是no bindings,即消息生产者和消息消费者没有被正确的绑定导致的惨案:
09.jpg
明白问题之后我们手动添加绑定关系,按如图所示填写绑定信息然后点击Bind按钮绑定:
10.jpg
之后再次使用Postman请求多次http://localhost:8030/feign/port/🐕,并访问http://localhost:15672/#/exchanges查看Excahnges选项卡的hystrixStreamOutput详情页可以发现消息已经被正确消费:
12.jpg
访问http://localhost:8070/hystrix,在输入框输入http://localhost:8090/turbine.stream并点击Monitor Stream按钮,跳转到Hystrix Monitor页面之后会发现聚合数据也已经正确显示了:
11.jpg