服务熔断-Hystrix
为什么需要断路器
在微服务架构中,我们将业务拆分成一个个的服务,服务与服务之间可以相互调用(RPC)。为了保证其高可用,单个服务又必须集群部署。由于网络原因或者自身的原因,服务并不能保证服务的100%可用,如果单个服务出现问题,调用这个服务就会出现网络延迟,此时若有大量的网络涌入,会形成任务累计,导致服务瘫痪,甚至导致服务“雪崩”。为了解决这个问题,就出现断路器模型。
简单理解:当微服务A
调用微服务B
。微服务B
调用微服务C
。微服务C
调用微服务D
。当调用的链路非常多时。假设微服务D
因为其他原因不可用。微服务A
在占用资源等待返回,如果流量访问过大,瞬间将微服务A
的资源用完,服务器可能崩溃。导致很多问题。形成雪崩效应
Hystrix概述
Hystrix
是用于处理分布式系统的延迟和容错
的开源库,在分布式系统中,某一个服务的超时、异常是必不可免的。Hystrix
能保证就算服务错误的情况下,也返回一些提示,从而解决一些整体服务失败,避免级联故障,提高分布式系统的弹性
。
测试环境搭建
1、
创建主工程,空的maven
项目
2、
导入依赖,并删除src
目录
<?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>
<groupId>com.wyx</groupId>
<artifactId>Hystrix</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<project.build.sourceEmcoding>UTF-8</project.build.sourceEmcoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<!--对应的版本-->
<spring.boot.dependencies.version>2.4.3</spring.boot.dependencies.version>
<spring.cloud.dependencies.version>2020.0.2</spring.cloud.dependencies.version>
<spring.cloud.alibaba.dependencies.version>2.2.1.RELEASE</spring.cloud.alibaba.dependencies.version>
<mysql.version>8.0.23</mysql.version>
<druid.version>1.2.5</druid.version>
<druid.spring.boot.version>1.2.5</druid.spring.boot.version>
<log4j.version>1.2.17</log4j.version>
<junit.version>4.13</junit.version>
<lombok.version>1.18.20</lombok.version>
<mybatis.spring.boot.version>2.1.4</mybatis.spring.boot.version>
</properties>
<dependencyManagement>
<dependencies>
<!--SpringBoot 依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring.boot.dependencies.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--Spring Cloud 依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring.cloud.dependencies.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--Spring Cloud Alibaba 依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring.cloud.alibaba.dependencies.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--Mysql 连接驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<!--druid 依赖-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid.version}</version>
</dependency>
<!--Spring Boot 启动器-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>${druid.spring.boot.version}</version>
</dependency>
<!--Lombok 依赖-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>
<!--log4j 依赖-->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<!--junit 单元测试 依赖-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
</dependency>
<!--Mybatis-spring-boot 启动器-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>${mybatis.spring.boot.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.4.4</version>
<configuration>
<fork>true</fork>
<addResources>true</addResources>
</configuration>
</plugin>
</plugins>
</build>
</project>
微服务提供者
1、
在主工程下提交空的maven
项目 cloud-provider-hystrix8001,并导入依赖
这里使用consul做注册中心:不会使用consul
参考这里:Consul注册中心的使用
<dependencies>
<!--连接 consul 的依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
<version>2.2.8.RELEASE</version>
</dependency>
<!--spring-boot-web 模块 常用的3个-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</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.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<!--测试插件-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test</artifactId>
<scope>test</scope>
</dependency>
<!--lombok 依赖-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
2、
创建application.yml
server:
port: 8001
spring:
application:
name: cloud-provider-hystrix
cloud:
consul:
# 服务的主机
host: localhost
# 服务的端口号
port: 8500
discovery:
# 注册到服务中心的名称
service-name: ${spring.application.name}
3、
主启动类
package com.wyx.cloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
public class ProviderHystrixMain8001 {
public static void main(String[] args) {
SpringApplication.run(ProviderHystrixMain8001.class,args);
}
}
4、
业务逻辑
package com.wyx.cloud.service;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.springframework.stereotype.Service;
@Service
public class Provider {
public String getInfo(){
return "获取服务成功!😀😀😀😀";
}
@HystrixCommand(fallbackMethod = "getInfoOutTimeHandler",commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "2000")
})
public String getInfoOutTime(){
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "Error:获取服务失败!!!😂😂😂😂";
}
}
package com.wyx.cloud.controller;
import com.wyx.cloud.service.Provider;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@RestController
public class ProviderController {
@Resource
Provider provider;
@GetMapping("/getInfo")
public String getInfo(){
return provider.getInfo();
}
@GetMapping("/getInfoOutTime")
public String getInfoOutTime(){
return provider.getInfoOutTime();
}
}
微服务消费者
1、
创建空的maven工程 cloud-consumer-hystrix80 并导入依赖
<dependencies>
<!--连接 consul 的依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</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>
<version>2.2.8.RELEASE</version>
</dependency>
<!--spring-boot-web 模块 常用的3个-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</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.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<!--测试插件-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test</artifactId>
<scope>test</scope>
</dependency>
<!--lombok 依赖-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
2、
添加application.yml
文件
server:
port: 80
spring:
application:
name: cloud-consumer-hystrix
cloud:
consul:
# 服务的主机
host: localhost
# 服务的端口号
port: 8500
discovery:
# 注册到服务中心的名称
service-name: ${spring.application.name}
3、
创建主启动类
package com.wyx.cloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class ConsumerHystrixMain80 {
public static void main(String[] args) {
SpringApplication.run(ConsumerHystrixMain80.class,args);
}
}
4、
创建openfeign
的调用接口
package com.wyx.cloud.service;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.GetMapping;
@Service // 注入容器
@FeignClient("cloud-provider-hystrix") // 需要提供服务的服务注册名,也是服务提供者的spring.application.name
public interface Provider {
@GetMapping("/getInfo")
public String getInfo();
@GetMapping("/getInfoOutTime")
public String getInfoOutTime();
}
5、
创建控制业务接口
package com.wyx.cloud.controller;
import com.wyx.cloud.service.Provider;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@RestController
@Slf4j
public class ConsumerController {
@Resource
Provider provider;
@GetMapping("/getInfo")
public String getInfo(){
return provider.getInfo();
}
@GetMapping("/getInfoOutTime")
public String getInfoOutTime(){
return provider.getInfoOutTime();
}
}
使用jmeter
来做高并发测试:具体测试方法参考网上。
开启测试后、在访问时速度明显减慢。如果访问量继续增加,在真实环境下,服务器可能会宕机导致服务不可用,于是我们开始使用Hystrix
来解决以上出现的问题。
主要功能
服务降级
当提高服务的应用出现问题后,返回一些友好提示来保证其他服务的调用不会出错。Fallback
触发原因:程序运行异常
、返回超时
、服务熔断触发
、线程池资源不足
使用服务降级
:
在服务提供方使用服务降级:
1、导入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
<version>2.2.8.RELEASE</version>
</dependency>
2、
添加错误后调用的方法fallback
// 一般放在使用 @HystrixCommand 的类中
public String getInfoOutTimeHandler(){
return "访问超时!!!!";
}
3、
添加注解
/*
* @HystrixCommand 作用与方法上,
* fallbackMethod 出错后调用的方法
* commandProperties 配置超时的时间
* */
@HystrixCommand(fallbackMethod = "getInfoOutTimeHandler",commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "2000")
})
4、
主启动类添加自动开启注解
// 老版本可以使用 @EnableCircuitBreaker,新版本中该注解已经过时
@EnableHystrix
测试即可
修改微服务提供方的getInfoOutTime方法,在线程睡眠前面添加错误代码
int x = 10/0;
再次测试:发现这次就算不超时,也会走我们编写的getInfoOutTimeHandler
方法
总结:在@HystrixCommand
注解中,如果放回时间超时,或者程序运行时出现异常,等情况都会走我们编写的服务getInfoOutTimeHandler
方法
在服务消费端使用服务降级:
1、导入依赖
<!--老版本中自带了openfeign 自带了 hystrix 可以不用导入,新版本必须引入依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
<version>2.2.8.RELEASE</version>
</dependency>
注意:老版本虽然不用导入依赖,但是必须要在application.yml
中添加开启hystrix
功能
feign:
hystrix:
enable: true
2、
在主启动类上添加开启hystrix
功能
@EnableHystrix
3、
编写错误处理方法
public String getInfoOutTimeHandler(){
return "消费者80:运行出错或等待返回结果超时!!!🤢🤢🤢";
}
4、
在要处理的方法上添加注解
// 这里调节 1秒,然而服务器需要3秒才响应
@HystrixCommand(fallbackMethod = "getInfoOutTimeHandler",commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1000")
})
在上面的使用过程中出现了以下问题
- 每个方法都需要一个服务失败后的解决方法。
- 业务逻辑代码和出错解决方法混在一块,系统耦合度高。
下面针对以上问题,我们做一定的修改。
全局错误返回配置方法
1、
配置全局出错的方法
// 也是在类中
public String getGlobalFallbackMethod(){
return "全局错误返回错误的方法!!";
}
2、
在需要使用服务降级的类上添加服务降级的默认配置
// getGlobalFallbackMethod 为刚刚我们定义的方法
@DefaultProperties(defaultFallback = "getGlobalFallbackMethod")
3、
在需要进行服务降级的方法上添加注解
@HystrixCommand
注意点:这里配置了全局的出错处理,如果@HystrixCommand
详细配置了自己出错走的方法,就默认走自己的,没有就使用全局配置。
解耦业务逻辑代码的混乱问题
1、
编写一个类实现openfeign调用的服务接口
package com.wyx.cloud.service;
import org.springframework.stereotype.Component;
// 重写方法,如果服务错误就会调用这里的方法
@Component
public class ProviderFallBack implements Provider{
@Override
public String getInfo() {
String msg = "getInfo:解耦业务逻辑中出错的服务降级";
return msg;
}
@Override
public String getInfoOutTime() {
String msg = "getInfoOutTime:解耦业务逻辑中出错的服务降级";
return msg;
}
}
2、
修改接口的@FeignClient
注解
// 原来的:@FeignClient(value = "cloud-provider-hystrix")
// 修改添加 fallback 填写自己实现接口的类。
@FeignClient(value = "cloud-provider-hystrix",fallback = ProviderFallBack.class)
运行测试即可
服务熔断
熔断机制是应对雪崩效应的一种微服务链路保护机制。当扇出链路的某个微服务出错不可用或响应时间太长时,会进行服务的降级,进而熔断该阶段微服务调用,快速返回错误的响应信息。当检测到该节点微服务调用响应正常后,恢复调用链路。
原理图:
- Closed:熔断器关闭状态(所有请求返回成功)
- Open:熔断器打开状态(调用次数累计到达阈值或者比例,熔断器打开,服务直接返回错误)
- Half Open:熔断器半开状态(默认时间过后,进入半熔断状态,允许定量服务请求,如果调用都成功,则认为恢复了,则关闭断路器,反之打开断路器)
/*
* 以下为服务熔断代码
* */
@HystrixCommand(commandProperties = {
//设置服务熔断功能开启
@HystrixProperty(name="circuitBreaker.enabled",value = "true"),
//设置服务熔断请求次数,达到这个这个阈值才会触发熔断
@HystrixProperty(name="circuitBreaker.requestVolumeThreshold",value = "10"),
//设置服务熔断百分比;失败率超过这个百分比才能熔断。
@HystrixProperty(name="circuitBreaker.errorThresholdPercentage",value = "50"),
//设置服务熔断时间窗口期
@HystrixProperty(name="circuitBreaker.sleepWindowInMilliseconds",value = "10000")
})
@GetMapping("/ronduan/{id}")
public String ronDuan(@PathVariable int id){
if(id<0){
throw new RuntimeException("ID不可为负数!");
}
return "服务调用成功:"+id+":"+ UUID.randomUUID();
}
熔断器三个重要参数:快照时间窗、请求总数阈值、错误百分比阈值
快照时间窗:断路器确定是否打开需要统计一些请求和错误数据,而统计的时间范围就是快照时间窗,默认为最近的10秒;
请求总数阈值:在快照时间窗内,必须满足请求总数阈值才有资格熔断。默认为20,意味着在10秒内,如果该hystrix命令的调用次数不足20次,即使所有的请求都超时或者其他原因失败,断路器都不会打开。
错误百分比阈值:当请求总数在快照时间窗内超过了阈值,比如发生了30次调用,如果在这30次调用中,有15次发生了超时异常,也就是超过50%的错误百分比,在默认设定50%阈值情况下,这时候才会将熔断器打开。
全部配置:
//Command Properties
//Execution相关的属性的配置:
execution.isolation.strategy //隔离策略,默认是Thread, 可选Thread|Semaphore
execution.isolation.thread.timeoutInMilliseconds //命令执行超时时间,默认1000ms
execution.timeout.enabled //执行是否启用超时,默认启用true
execution.isolation.thread.interruptOnTimeout //发生超时是是否中断,默认true
execution.isolation.semaphore.maxConcurrentRequests //最大并发请求数,默认10,该参数当使用ExecutionIsolationStrategy.SEMAPHORE策略时才有效。如果达到最大并发请求数,请求会被拒绝。理论上选择semaphore size的原则和选择thread size一致,但选用semaphore时每次执行的单元要比较小且执行速度快(ms级别),否则的话应该用thread。semaphore应该占整个容器(tomcat)的线程池的一小部分。
//Fallback相关的属性
//这些参数可以应用于Hystrix的THREAD和SEMAPHORE策略
fallback.isolation.semaphore.maxConcurrentRequests //如果并发数达到该设置值,请求会被拒绝和抛出异常并且fallback不会被调用。默认10
fallback.enabled //当执行失败或者请求被拒绝,是否会尝试调用hystrixCommand.getFallback() 。默认true
//Circuit Breaker相关的属性
default.circuitBreaker.enabled //用来跟踪circuit的健康性,如果未达标则让request短路。默认true
circuitBreaker.requestVolumeThreshold 一个rolling window内最小的请求数。如果设为20,那么当一个rolling window的时间内(比如说1个rolling window是10秒)收到19个请求,即使19个请求都失败,也不会触发circuit break。默认20
circuitBreaker.sleepWindowInMilliseconds //触发短路的时间值,当该值设为5000时,则当触发circuit break后的5000毫秒内都会拒绝request,也就是5000毫秒后才会关闭circuit。默认5000
circuitBreaker.errorThresholdPercentage //错误比率阀值,如果错误率>=该值,circuit会被打开,并短路所有请求触发fallback。默认50
circuitBreaker.forceOpen //强制打开熔断器,如果打开这个开关,那么拒绝所有request,默认false
circuitBreaker.forceClosed //强制关闭熔断器 如果这个开关打开,circuit将一直关闭且忽略circuitBreaker.errorThresholdPercentage
//Metrics相关参数
metrics.rollingStats.timeInMilliseconds //设置统计的时间窗口值的,毫秒值,circuit break 的打开会根据1个rolling window的统计来计算。若rolling window被设为10000毫秒,则rolling window会被分成n个buckets,每个bucket包含success,failure,timeout,rejection的次数的统计信息。默认10000
metrics.rollingStats.numBuckets //设置一个rolling window被划分的数量,若numBuckets=10,rolling window=10000,那么一个bucket的时间即1秒。必须符合rolling window % numberBuckets == 0。默认10
metrics.rollingPercentile.enabled //执行时是否enable指标的计算和跟踪,默认true
metrics.rollingPercentile.timeInMilliseconds //设置rolling percentile window的时间,默认60000
metrics.rollingPercentile.numBuckets //设置rolling percentile window的numberBuckets。逻辑同上。默认6
metrics.rollingPercentile.bucketSize //如果bucket size=100,window=10s,若这10s里有500次执行,只有最后100次执行会被统计到bucket里去。增加该值会增加内存开销以及排序的开销。默认100
metrics.healthSnapshot.intervalInMilliseconds //记录health 快照(用来统计成功和错误绿)的间隔,默认500ms
//Request Context 相关参数
requestCache.enabled //默认true,需要重载getCacheKey(),返回null时不缓存
requestLog.enabled //记录日志到HystrixRequestLog,默认true
//Collapser Properties 相关参数
hystrix.collapser.default.maxRequestsInBatch //单次批处理的最大请求数,达到该数量触发批处理,默认Integer.MAX_VALUE
hystrix.collapser.default.timerDelayInMilliseconds //触发批处理的延迟,也可以为创建批处理的时间+该值,默认10
hystrix.collapser.default.requestCache.enabled //是否对HystrixCollapser.execute() and HystrixCollapser.queue()的cache,默认true
//ThreadPool 相关参数
//线程数默认值10适用于大部分情况(有时可以设置得更小),如果需要设置得更大,那有个基本得公式可以follow:
//requests per second at peak when healthy × 99th percentile latency in seconds + some breathing room
//每秒最大支撑的请求数 (99%平均响应时间 + 缓存值)
//比如:每秒能处理1000个请求,99%的请求响应时间是60ms,那么公式是:
//(0.060+0.012)
//基本得原则时保持线程池尽可能小,他主要是为了释放压力,防止资源被阻塞。
//当一切都是正常的时候,线程池一般仅会有1到2个线程激活来提供服务
hystrix.threadpool.default.coreSize //并发执行的最大线程数,默认10
hystrix.threadpool.default.maxQueueSize //BlockingQueue的最大队列数,当设为-1,会使用SynchronousQueue,值为正时使用LinkedBlcokingQueue。该设置只会在初始化时有效,之后不能修改threadpool的queue size,除非reinitialising thread executor。默认-1。
hystrix.threadpool.default.queueSizeRejectionThreshold //即使maxQueueSize没有达到,达到queueSizeRejectionThreshold该值后,请求也会被拒绝。因为maxQueueSize不能被动态修改,这个参数将允许我们动态设置该值。if maxQueueSize == -1,该字段将不起作用
hystrix.threadpool.default.keepAliveTimeMinutes //如果corePoolSize和maxPoolSize设成一样(默认实现)该设置无效。如果通过plugin(https://github.com/Netflix/Hystrix/wiki/Plugins)使用自定义实现,该设置才有用,默认1.
hystrix.threadpool.default.metrics.rollingStats.timeInMilliseconds //线程池统计指标的时间,默认10000
hystrix.threadpool.default.metrics.rollingStats.numBuckets 将rolling //window划分为n个buckets,默认10
服务限流
在面对高并发的流量,如同秒杀业务时,将访问排队后一个一个经行处理。
后面使用alibaba的Sentinel说明
实时监控
在微服务架构中,Hystrix 除了实现容错外,还提供了实时监控功能。在服务调用时,Hystrix 会实时累积关于 HystrixCommand 的执行信息,比如每秒的请求数、成功数等。
下面我们来配置一个实时监控页面
1、
新建项目:cloud-hystrix-dashboard9001
2、
导入pom.xml
<dependencies>
<!--新增hystrix dashboard-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
<version>2.2.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
3、
创建application.yml
server:
port: 9001
# 开启权限
hystrix:
dashboard:
proxy-stream-allow-list: "*"
4、
主启动类:@EnableHystrixDashboard
package com.wyx.cloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;
@SpringBootApplication
@EnableHystrixDashboard
public class HystrixDashboardMain9001 {
public static void main(String[] args) {
SpringApplication.run(HystrixDashboardMain9001.class, args);
}
}
5、
启动程序访问测试:http://localhost:9001/hystrix
6、
修改8001和80,检测是否有如下依赖,没有则添加
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
7、
主启动类下注入以下bean
@Bean
public ServletRegistrationBean getServlet(){
HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet();
ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet);
registrationBean.setLoadOnStartup(1);
registrationBean.addUrlMappings("/hystrix.stream"); //访问路径
registrationBean.setName("HystrixMetricsStreamServlet");
return registrationBean;
}
8、
访问服务带有熔断的服务
9、
访问http://localhost:9001/hystrix,填写监控入口。如下:
图表参数说明: