复杂分布式体系结构中的应用程序有数十个依赖关系,每个依赖关系在某些时候将不可避免地失败。
服务雪崩
多个微服务之间调用的时候,假设微服务A调用微服务B和微服务C,微服务B和微服务C又调用其它的微服务,这就是所谓的"扇出"。
如果扇出的链路上某个微服务的调用响应时间过长或者不可用,对微服务A的调用就会占用越来越多的系统资源,进而引起系统崩溃,所谓的"雪崩效应"。
对于高流量的应用来说,单一的后端依赖可能会导致所有服务器上的所有资源都在几秒钟内饱和。比失败更糟糕的是,这些应用程序还可能导致服务之间的延迟增加、备份队列,线程和其他系统紧张,导致整个系统发生更多的级联故障。这些都表示需要对故障和延迟进行隔离和管理,以便单个依赖关系的失败,不能取消整个应用程序或系统。
所以,通常当你发现一个模块下的某个实例失败后,这时候这个模块依然还会接收流量,然后这个有问题的模块还调用了其他的模块,这样就会发生级联故障,或者叫雪崩。
Hystrix是一个用于处理分布式系统的延迟和容错的开源库,在分布式系统里,许多依赖不可避免的会调用失败。比如超时、异常等。
Hystrix能够保证在一个依赖出问题的情况下,不会导致整体服务失败,避免级联故障,以提高分布式系统的弹性。
"断路器"本身是一种开关装置,当某个服务单元发生故障之后,通过断路器的故障监控(类似熔断保险丝),向调用方返回一个符合预期的、可处理的备选响应(FallBack),而不是长时间的等待或者抛出调用方无法处理的异常,这样就保证了服务调用方的线程不会被长时间、不必要地占用,从而避免了故障在分布式系统中的蔓延,乃至雪崩。
比如服务器忙,不让客户端等待并立刻返回一个友好提示,fallback。
下列情况都会触发降级
当某个服务出现问题,卡死了,不能让用户一直等待,需要关闭所有对此服务的访问,然后调用服务降级。
三步骤: 服务的降级->进而熔断->恢复调用链路。
秒杀高并发等操作,不能让所有访问用户瞬间都访问服务器,限制一次只可以有多少请求。
1.新建cloud-provider-hystrix-payment8001
2.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">
<parent>
<artifactId>cloud123</artifactId>
<groupId>com.atguigu.springcloud</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cloud-provider-hystrix-payment8001</artifactId>
<dependencies>
<!--新增hystrix-->
<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-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>com.atguigu.springcloud</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>${
project.version}</version>
</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.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>
</project>
2.application.yml
server:
port: 8001
eureka:
client:
register-with-eureka: true #表识不向注册中心注册自己
fetch-registry: true #表示自己就是注册中心,职责是维护服务实例,并不需要去检索服务
service-url:
# defaultZone: http://eureka7002.com:7002/eureka/ #设置与eureka server交互的地址查询服务和注册服务都需要依赖这个地址
defaultZone: http://eureka7001.com:7001/eureka/
# server:
# enable-self-preservation: false
spring:
application:
name: cloud-provider-hystrix-payment
# eviction-interval-timer-in-ms: 2000
3.主启动
@SpringBootApplication
@EnableEurekaClient
public class PaymentHystrixMain8001 {
public static void main(String[] args) {
SpringApplication.run(PaymentHystrixMain8001.class,args);
}
}
4.业务类
4.1service(PaymentService)
@Service
public class PaymentService {
//成功
public String paymentInfo_OK(Integer id){
return "线程池:"+Thread.currentThread().getName()+ " paymentInfo_OK,id:"+id+"\t"+"哈哈哈";
}
//失败
public String paymentInfo_TimeOut(Integer id){
//延时3s执行,模拟处理业务复杂
int timeNumber = 3;
try{
TimeUnit.SECONDS.sleep(timeNumber);
}catch (Exception e){
e.printStackTrace();
}
return "线程池:"+Thread.currentThread().getName()+ " paymentInfo_TimeOut,id:"+id+"\t"+"哈哈哈"+" 耗时(秒):"+timeNumber;
}
}
4.2controller(PaymentController)
@RestController
@Slf4j
public class PaymentController {
@Autowired
private PaymentService paymentService;
@Value("${server.port}")
private String serverPort;
@GetMapping("/payment/hystrix/ok/{id}")
public String paymentInfo_OK(@PathVariable("id") Integer id){
String result = paymentService.paymentInfo_OK(id);
log.info("***********result:"+result);
return result;
}
@GetMapping("/payment/hystrix/timeout/{id}")
public String paymentInfo_TimeOut(@PathVariable("id") Integer id){
String result = paymentService.paymentInfo_TimeOut(id);
log.info("*******result:"+result);
return result;
}
}
接下来,将以上述为根基平台,从正确->错误->降级熔断->恢复,来演示Hystrix的使用。
此时使用Jmeter压测工具,来20000个并发压死8001,20000个请求都去访问paymentInfo_TimeOut服务,压测中,发现,另外一个方法并没有被压测,但是我们访问它时,却需要等待,这就是因为被压测的方法它占用了服务器大部分资源,导致其他请求也变慢了。
一句话来说:tomcat的默认工作线程数被打满了,没有多余的线程来分解压力和处理。
上面还是服务提供者8001自己测试,如果此时外部的消费者80也来访问,那消费者只能干等,最终导致消费端80不满意,服务端8001直接被拖死。
1.新建cloud-consumer-feign-hystrix-order80 Module。
2.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">
<parent>
<artifactId>cloud123</artifactId>
<groupId>com.atguigu.springcloud</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cloud-consumer-feign-hystrix-order80</artifactId>
<dependencies>
<!--新增hystrix-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</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-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>com.atguigu.springcloud</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>${
project.version}</version>
</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.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>
</project>
3.application.yml
eureka:
client:
register-with-eureka: true #表识不向注册中心注册自己
fetch-registry: true #表示自己就是注册中心,职责是维护服务实例,并不需要去检索服务
service-url:
defaultZone: http://eureka7001.com:7001/eureka/
spring:
application:
name: cloud-provider-hystrix-order
server:
port: 80
4.主启动类
@SpringBootApplication
@EnableFeignClients
public class OrderHystrixMain80 {
public static void main(String[] args) {
SpringApplication.run(OrderHystrixMain80.class,args);
}
}
5.业务类
5.1 PaymentHystrixService
@Component
@FeignClient(value = "CLOUD-PROVIDER-HYSTRIX-PAYMENT")
public interface PaymentHystrixService {
@GetMapping("/payment/hystrix/ok/{id}")
String paymentInfo_OK(@PathVariable("id") Integer id);
@GetMapping("/payment/hystrix/timeout/{id}")
String paymentInfo_TimeOut(@PathVariable("id") Integer id);
}
5.2 OrderHystrixController
@RestController
@Slf4j
public class OrderHystrixController {
@Autowired
private PaymentHystrixService paymentHystrixServicel;
@GetMapping("/consumer/payment/hystrix/ok/{id}")
public String paymentInfo_OK(@PathVariable("id") Integer id){
return paymentHystrixServicel.paymentInfo_OK(id);
}
@GetMapping("/consumer/payment/hystrix/timeout/{id}")
public String paymentInfo_TimeOut(@PathVariable("id") Integer id){
return paymentHystrixServicel.paymentInfo_TimeOut(id);
}
}
启动order80模块,访问pay,再次压测20000个并发,此时80消费者要么转圈圈等待,访问变慢,要么消费者报超时错误。
原因是:8001同一层次的其他接口服务被困死,因为tomcat线程里面的工作线程已经被挤占完毕,80此时调用8001,客户端访问响应缓慢,转圈圈。
现在我们有两个问题需要解决:
解决办法
设置自身调用超时时间的峰值,峰值内可以正常运行,超过了需要有兜底的方法处理,作服务降级fallback。
在业务类启动@HystrixCommand注解
@Service
public class PaymentService {
//成功
public String paymentInfo_OK(Integer id){
return "线程池:"+Thread.currentThread().getName()+ " paymentInfo_OK,id:"+id+"\t"+"哈哈哈";
}
//失败
@HystrixCommand(fallbackMethod = "paymentInfo_TimeOutHandler",commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "3000") //3秒钟以内就是正常的业务逻辑
})
public String paymentInfo_TimeOut(Integer id){
//延时3s执行,模拟处理业务复杂
int timeNumber = 5;
try{
TimeUnit.SECONDS.sleep(timeNumber);
}catch (Exception e){
e.printStackTrace();
}
return "线程池:"+Thread.currentThread().getName()+ " paymentInfo_TimeOut,id:"+id+"\t"+"哈哈哈"+" 耗时(秒):"+timeNumber;
}
//兜底方法
public String paymentInfo_TimeOutHandler(Integer id ){
return "线程池:"+Thread.currentThread().getName()+ " 系统繁忙,请稍候再试,id:"+id+"\t"+"哭了吧唧";
}
}
一旦调用服务方法失败并抛出了错误信息后,会自动调用@HystrixCommand标注好的fallbackMethod调用类中的指定方法。
比如上述方法中,我们设置了@HystrixProperty(name = “execution.isolation.thread.timeoutInMilliseconds”,value = “3000”),也就是说,3s之内执行完这个业务方法是正确的,一旦这个业务方法执行超过3s,就会自动会调用paymentInfo_TimeOutHandler方法。
在主启动类中进行激活,添加@EnableCircuitBreaker
@SpringBootApplication
@EnableEurekaClient
@EnableCircuitBreaker
public class PaymentHystrixMain8001 {
public static void main(String[] args) {
SpringApplication.run(PaymentHystrixMain8001.class,args);
}
}
上面只是超时测试,我们也可以对该方法进行错误测试,修改代码如下:
//失败
@HystrixCommand(fallbackMethod = "paymentInfo_TimeOutHandler",commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "3000") //3秒钟以内就是正常的业务逻辑
})
public String paymentInfo_TimeOut(Integer id){
//延时3s执行,模拟处理业务复杂
// int timeNumber = 5;
// try{
// TimeUnit.SECONDS.sleep(timeNumber);
// }catch (Exception e){
// e.printStackTrace();
// }
int i = 10/0; //故意出错。
return "线程池:"+Thread.currentThread().getName()+ " paymentInfo_TimeOut,id:"+id+"\t"+"哈哈哈"+" 耗时(秒):";
}
只要当前服务不可用了(超时或异常),就做服务降级,兜底的方案都是paymentInfo_TimeOutHandler。
80订单微服务,也可以更好的保护自己。可以根据8001服务依然画葫芦进行服务降级。
1.修改YML
eureka:
client:
register-with-eureka: true #表识不向注册中心注册自己
fetch-registry: true #表示自己就是注册中心,职责是维护服务实例,并不需要去检索服务
service-url:
defaultZone: http://eureka7001.com:7001/eureka/
spring:
application:
name: cloud-provider-hystrix-order
server:
port: 80
feign:
hystrix:
enabled: true #如果处理自身的容错就开启。开启方式与生产端不一样。
2.主启动类上添加@EnableHystrix注解
@SpringBootApplication
@EnableFeignClients
@EnableHystrix
public class OrderHystrixMain80 {
public static void main(String[] args) {
SpringApplication.run(OrderHystrixMain80.class,args);
}
}
3.修改contrller
@RestController
@Slf4j
public class OrderHystrixController {
@Autowired
private PaymentHystrixService paymentHystrixServicel;
@GetMapping("/consumer/payment/hystrix/ok/{id}")
public String paymentInfo_OK(@PathVariable("id") Integer id){
return paymentHystrixServicel.paymentInfo_OK(id);
}
@GetMapping("/consumer/payment/hystrix/timeout/{id}")
@HystrixCommand(fallbackMethod = "paymentTimeOutFallbackMethod",commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "1500") //1.5秒钟以内就是正常的业务逻辑
})
public String paymentInfo_TimeOut(@PathVariable("id") Integer id){
String result = paymentHystrixServicel.paymentInfo_TimeOut(id);
return result;
}
//兜底方法
public String paymentTimeOutFallbackMethod(@PathVariable("id") Integer id){
return "我是消费者80,对付支付系统繁忙请10秒钟后再试或者自己运行出错请检查自己,(┬_┬)";
}
}
配置一个全局的降级方法,所有方法都可以走这个降级方法,至于某些特殊创建,再单独创建降级方法。
@DefaultProperties(defaultFallback="")注解,为所有方法指定统一的降级方法,前提是当前方法需要指定@HystrixCommand注解,如果@HystrixCommand注解指定了降级方法,就用@HystrixCommand注解指定的,如果没有就用全局降级方法。
设计理念
1.修改80模块的controller代码如下:
@RestController
@Slf4j
//指定这个方法为全局的降级方法,当业务类没有指定降级方法时,
//就使用这个方法作为降级方法,前提业务量有@HystrixCommand注解。
@DefaultProperties(defaultFallback = "payment_Global_FallbackMethod")
public class OrderHystrixController {
@Autowired
private PaymentHystrixService paymentHystrixServicel;
@GetMapping("/consumer/payment/hystrix/ok/{id}")
public String paymentInfo_OK(@PathVariable("id") Integer id){
return paymentHystrixServicel.paymentInfo_OK(id);
}
@GetMapping("/consumer/payment/hystrix/timeout/{id}")
// @HystrixCommand(fallbackMethod = "paymentTimeOutFallbackMethod",commandProperties = {
// @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "1500") //3秒钟以内就是正常的业务逻辑
// })
@HystrixCommand //不指定降级方法,就使用全局设置的降级方法
public String paymentInfo_TimeOut(@PathVariable("id") Integer id){
int age = 1/0;
String result = paymentHystrixServicel.paymentInfo_TimeOut(id);
return result;
}
//兜底方法
public String paymentTimeOutFallbackMethod(@PathVariable("id") Integer id){
return "我是消费者80,对付支付系统繁忙请10秒钟后再试或者自己运行出错请检查自己,(┬_┬)";
}
//下面是全局fallback方法
public String payment_Global_FallbackMethod(){
return "Global异常处理信息,请稍后再试,(┬_┬)";
}
}
需求:客户端去调用服务端,碰上服务端宕机或关闭。
本次案例服务降级处理是再客户端80实现完成的,服务端8001就不服务降级了。我们只需要再Feign客户端定义的接口添加一个服务降级处理的实现类即可实现解耦。
1.根据80模块已经有的PaymentHystrixService接口,重新新建一个类(PaymentFallbackService)实现该接口,统一为接口里面的方法进行异常处理。
@Component
public class PaymentFallbackService implements PaymentHystrixService {
@Override
public String paymentInfo_OK(Integer id) {
return "-----PaymentFallbackService fall back-paymentInfo_OK , (┬_┬)";
}
@Override
public String paymentInfo_TimeOut(Integer id) {
return "-----PaymentFallbackService fall back-paymentInfo_TimeOut , (┬_┬)";
}
}
PayService接口是远程调用8001模块,当调用8001模块中的方法时,出现了错误时,就需要降级方法来进行处理。
实现类中的方法,刚好与接口中的方法一一对应。并且实现类中的方法作为降级方法,当客户端调用接口中的方法出错时,就会调用实现类中对应的降级方法进行处理。
2.修改配置文件,添加:
feign:
hystrix:
enabled: true #如果处理自身的容错就开启。开启方式与生产端不一样。
3.让PayService的实现类生效:
在@FeignClient注解中指定fallback属性值为PayService接口的实现类字节码文件,代码如下:
@Component
@FeignClient(value = "CLOUD-PROVIDER-HYSTRIX-PAYMENT",fallback = PaymentFallbackService.class)
public interface PaymentHystrixService {
@GetMapping("/payment/hystrix/ok/{id}")
String paymentInfo_OK(@PathVariable("id") Integer id);
@GetMapping("/payment/hystrix/timeout/{id}")
String paymentInfo_TimeOut(@PathVariable("id") Integer id);
}
当请求过来,首先还是通过Feign远程调用8001模块对应的方法,但是如果8001模块出错,调用失败,那么就会调用PaymentFallbackService类的当前同名的方法,作为降级方法。
测试:
此时将8001模块服务关闭,来演示服务宕机的错误,80模块再次访问:
可以看到,并没有报800错误,而是降级访问实现类的同名方法,这样即使服务器挂了,用户不用一直等待,或者报错。
问题:这样虽然解决了代码耦合度文图,但是又出现了过多重复代码的问题,每个方法都有一个降级方法。
类比保险丝达到最大服务访问后,直接拒绝访问,拉闸限电,然后调用服务降级的方法并返回友好提示。
就是保险丝:服务的降级->进而熔断->恢复调用链路。
比如并发到达10000后,我们就拒绝其他用户访问,如果在有用户访问,就调用降级方法返回给用户。
熔断机制概述:
熔断机制是应对雪崩效应的一种微服务链路保护机制。当扇出链路的某个微服务出错不可用或者响应时间太长时,会进行服务的降级,进而熔断该节点微服务的调用,快速返回错误的响应信息。
当检测到该节点微服务调用响应正常后,恢复调用链路。
在SpringCloud框架里,熔断机制通过Hystrix实现。Hystrix会监控服务间调用的状况,当失败的调用到一定阈值,缺省是5秒内20次调用失败,就会启动熔断机制。熔断机制的注解是@HystrixCommand。
修改cloud-provider-hystrix-payment8001
1.修改PayService接口,添加服务熔断相关的方法
//服务熔断 //降级方法
@HystrixCommand(fallbackMethod = "paymentCircuitBreaker_fallback",commandProperties = {
@HystrixProperty(name = "circuitBreaker.enabled",value = "true"), //是否开启断路器
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold",value = "10"), //请求次数 并发超过这个次数,开启断路器
@HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds",value = "10000"), //时间范围
@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage",value = "60"), //失败率达到多少后跳闸 60%
//比如,10次请求,6次失败,则跳闸。
})
public String paymentCircuitBreaker(@PathVariable("id") Integer id){
if (id < 0){
throw new RuntimeException("*****id 不能负数");
}
String serialNumber = IdUtil.simpleUUID();
return Thread.currentThread().getName()+"\t"+"调用成功,流水号:"+serialNumber;
}
public String paymentCircuitBreaker_fallback(@PathVariable("id") Integer id){
return "id 不能负数,请稍候再试,(┬_┬)/~~ id: " +id;
}
@HystrixProperty注解整体意思是:
10秒之内(窗口,会移动),如果并发超过10个,或者10个并发中,失败了6个,就开启熔断器。
涉及到断路器的三个重要参数:快照时间窗,请求总数阈值、错误百分比阈值。
IdUtil是Hutool包下的类,这个Hutool就是整合了所有的常用方法,比如UUID,反射,IO流等工具方法什么的都整合了。
@HystrixProperty注解name属性可配置哪些值,可以去 HystrixCommandProperties抽象类去了解。
2.修改controller
添加一个测试方法
//===服务熔断
@GetMapping("/payment/circuit/{id}")
public String paymentCircuitBreaker(@PathVariable("id") Integer id){
String result = paymentService.paymentCircuitBreaker(id);
log.info("*******result:"+result);
return result;
}
启动80、8001模块
多次访问,并且错误率超过60%。
此时服务熔断,此时即使访问正确的也会报错。
但是,当过了几秒后,又恢复了。
因为在10 秒窗口期内,它自己会尝试接收部分请求,发现服务可以正常调用,慢慢的当错误率低于60%,取消熔断器。
1请求进来,首先查询缓存,如果缓存有,直接返回
如果缓存没有,--->2
2,查看断路器是否开启,如果开启的,Hystrix直接将请求转发到降级返回,然后返回
如果断路器是关闭的,
判断线程池等资源是否已经满了,如果已经满了
也会走降级方法
如果资源没有满,判断我们使用的什么类型的Hystrix,决定调用构造方法还是run方法
然后处理请求
然后Hystrix将本次请求的结果信息汇报给断路器,因为断路器此时可能是开启的
(因为断路器开启也是可以接收请求的)
断路器收到信息,判断是否符合开启或关闭断路器的条件,
如果本次请求处理失败,又会进入降级方法
如果处理成功,判断处理是否超时,如果超时了,也进入降级方法
最后,没有超时,则本次请求处理成功,将结果返回给controller
除了隔离依赖服务的调用以外,Hystrix还提供了准实时的调用监控(Hystrix Dashboard),Hystrix会持续地记录所有通过Hystrix发起的请求的执行信息,并以统计报表和图形的形式展示给用户,包括每秒执行多少请求多少成功,多少失败等。Netflix通过hystrix-metrics-event-stream项目实现了对以上指标的监控。Spring Cloud也提供了Hystrix Dashboard的整合,对监控可视化界面。
1.新建cloud-consumer-hystrix-dashboard9001
2.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">
<parent>
<artifactId>cloud123</artifactId>
<groupId>com.atguigu.springcloud</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cloud-consumer-hystrix-dashboard9001</artifactId>
<dependencies>
<!--新增hystrix dashboard-->
<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>
<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>
</project>
3.application.yml
server:
port: 9001
4.主启动类
需要添加新注解@EnableHystrixDashboard
@SpringBootApplication
@EnableHystrixDashboard
public class HystrixDashboardMain9001 {
public static void main(String[] args) {
SpringApplication.run(HystrixDashboardMain9001.class,args);
}
}
5.所有Provider微服务提供类(8001/8002/8003)都需要监控依赖配置
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
之前的pom文件中都已经添加过了,这个是springboot的监控组件。
6.启动9001即可,访问:localhost:9001/hystrix,出现如下界面:
7.注意,此时仅仅是可以访问HystrixDashboard,并不代表已经监控了8001,8002,如果要监控,还需要配置。
以8001为例,在主启动类添加
@SpringBootApplication
@EnableEurekaClient
@EnableCircuitBreaker
public class PaymentHystrixMain8001 {
public static void main(String[] args) {
SpringApplication.run(PaymentHystrixMain8001.class,args);
}
/**
* 此配置是为了服务监控而配置,与服务容错本身无关,springcloud升级后的坑
* ServletRegistrationBean因为springboot的默认路径不是"/hystrix.stream",
* 只要再自己的项目里配置上下面的servlet就可以了
* */
@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;
}
}
其余的8002,8003等也是如此。
8.启动7001,8001,9001
然后在web界面,指定9001要监控8001:
实心圈的含义:
它通过颜色的变化代表了实例的健康程度,它的健康度从绿色<黄色<橙色<红色递减。
该实心圆除了颜色的变化之外,它的大小也会根据实例的请求流量发生变化,流量越大该实心圆就越大。所以通过该实心圆的展示,就可以在大量的实例中快速的发现故障实例和高压力实例。