1.Hystrix
用户的一个请求可能依赖几个服务,如果其中一个不可用,用户的整个请求会处于阻塞状态,高并发的情况下几秒钟可能就使整个服务线程负载处于饱和的状态下。由于服务的依赖性,会使整个服务都不可用,即雪崩效应。
首先当服务的某个API接口的失败次数小于阈值时,熔断器处于关闭状态,当失败的次数大于设定的阈值时,打开熔断器,请求会执行快速失败的逻辑,请求线程不会阻塞,处于打开状态的熔断器一段时间会半打开,并将一定数量的请求执行正常的逻辑,若成功,熔断器关闭,若失败熔断器继续打开。
2.在RestTemplate和Ribbon上使用熔断器
首先在Ribbon的工程中使用Hystrix
添加Hystrix的依赖:
<?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.wx</groupId>
<artifactId>learnspringcloud</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- <relativePath/>--> <!-- lookup parent from repository -->
</parent>
<groupId>com.wx</groupId>
<artifactId>eureka-ribbon-client</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>eureka-ribbon-client</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-eureka -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
<version>1.4.4.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-ribbon -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
<version>1.4.5.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-hystrix -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
<version>1.4.5.RELEASE</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
其次在调用服务的方法上加上注解:@HystrixCommand,指明回调函数,回调函数的参数好像要和hi方法的一样,不然会报找不到回调的错误。
启动类上要开启熔断器的功能:
启动一个eureka server,一个eureka clent工程,和一个ribbon客户端,
关掉eureka client服务
这样做的好处就是通过快速失败,请求能够得到及时处理,线程不再阻塞。
3.在Fegin中使用熔断器
由于Fegin在集成了Hystrix,不需要引入任何依赖,只需要在yml文件张开启hystrix的功能。
添加回调函数:
编写回调函数:
测试:
关闭eureka client:
经过测试,发现不管是RestTemplate,还是Fegin中使用断路器,第一个进入的方法总是回调函数的方法。因为hystrix 默认超时的时间是1s,如果1秒内没有响应,就会被认为服务有问题;此处将默认时间设置成为5秒,避免首次进去的就是fallback方法。
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 5000
4.使用Hystrix Dashboard监控熔断器
因为熔断器的状况反应了一个程序的可用性和健壮性,所以需要监控他。在微服务架构中为例保证程序的可用性,防止程序出错导致网络阻塞,出现了断路器模型。断路器的状况反应了一个程序的可用性和健壮性,它是一个重要指标。Hystrix Dashboard是作为断路器状态的一个组件,提供了数据监控和友好的图形化界面。
首先在RestTemplate中使用熔断器监控,我们就在ribbon-client工程中使用,加入起步依赖。Dashboard,Hystrix,Actuator。所以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">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.wx</groupId>
<artifactId>learnspringcloud</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- <relativePath/>--> <!-- lookup parent from repository -->
</parent>
<groupId>com.wx</groupId>
<artifactId>eureka-ribbon-client</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>eureka-ribbon-client</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-eureka -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
<version>1.4.4.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-ribbon -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
<version>1.4.5.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-hystrix -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
<version>1.4.5.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-hystrix-dashboard -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
<version>1.4.5.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-actuator -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<version>2.0.5.RELEASE</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
然后在启动类上加上注解@EnableHystrixDashboard,开启断路器监控功能。
启动eureka-server,eureka-client,eureka-ribbon-client., 访问http://localhost:8765/hystrix.stream,看不到熔断器的状态,
是springboot版本的问题2.0之后版本是这样,因为springboot的默认路径不是 "/hystrix.stream",需要配置yml文件再加上注解@EnableCircuitBreaker
@SpringBootApplication
@EnableEurekaClient
@EnableHystrix
@EnableCircuitBreaker
@EnableHystrixDashboard
public class EurekaRibbonClientApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaRibbonClientApplication.class, args);
}
}
然后再次启动,打包访问http://localhost:8765/actuator/hystrix.stream ping没有数据返回,熔断器没有数据返回,我突然想到可能是第一次访问到回调方法的原因。
所以我先访问一次http://localhost:8765/hi?name=Mr.Wang
然后ping就有数据了。
然后可以打开仪表盘看数据了 访问http://localhost:8765/hystrix
依次如图填写:
图中各个指标的含义如下:
其次是在Fegin中使用Hystrix Dashboard。在Fegin-client工程中加入起步依赖,和ribbon中加入的Dashboard依赖是一样的。虽然Fegin集成了Hystrix,但是Fegin自带的依赖不是起步依赖。
<?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.wx</groupId>
<artifactId>learnspringcloud</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- <relativePath/>--> <!-- lookup parent from repository -->
</parent>
<groupId>com.wx</groupId>
<artifactId>eureka-feign-client</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>eureka-feign-client</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
<version>1.4.4.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-feign -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
<version>1.4.5.RELEASE</version>
</dependency>
<!--断路器监控依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
<version>1.4.5.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-hystrix-dashboard -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
<version>1.4.5.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-actuator -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<version>2.0.5.RELEASE</version>
</dependency>
<!--断路器监控依赖-->
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
同样也需要在启动类上加上注解:
yml配置文件:
接下来打包,启动访问:
5.聚合监控
每一个Dashboard都有一个主页,当服务较多时,监控就非常的不方便,看单个的Hystrix Dashboard的数据并没有什么多大的价值,要想看这个系统的Hystrix Dashboard数据就需要用到Hystrix Turbine。Hystrix Turbine将每个服务Hystrix Dashboard数据进行了整合。Hystrix Turbine的使用非常简单,只需要引入相应的依赖和加上注解和配置就可以了。Turbine就是将多个Dashboard的数据放到一个页面来显示。新建一个工程名字为eureka-turbine-client
加入依赖:
<?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.wx</groupId>
<artifactId>learnspringcloud</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- <relativePath/>--> <!-- lookup parent from repository -->
</parent>
<groupId>com.wx</groupId>
<artifactId>eureka-turbine-client</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>eureka-turbine-client</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</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-hystrix-dashboard</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-turbine</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
yml文件:
server:
port: 8767
spring:
application:
name: service-turbine
eureka:
client:
serviceUrl:
defaultZone: http://peer1:8761/eureka/
management:
endpoints:
web:
exposure:
include: "*"
cors:
allowed-origins: "*"
allowed-methods: "*"
turbine:
app-config: eureka-ribbon-client,eureka-feign-client
aggregator:
clusterConfig: default
clusterNameExpression: new String("default")
combine-host: true
instanceUrlSuffix:
default: actuator/hystrix.stream
指定了要监控的两个服务名字,
启动类上加上注解:
打包启动注册中心,扶额u提供者,两个服务消费着,和监控服务。
访问http://localhost:8767/turbine.stream