1.概述
1.分布式系统面临的问题
在复杂的分布式架构系统里,服务之间的相互调用无法避免出现失败的情况。如果一个服务的调用链路比较长的时候,这种调用失败的概率会更高一些,比如A调用B,B调用C,C调用D这种长链路调用,又或者一个服务的调用需要依赖多个服务协作完成,这种调用失败的概率也会高一些,比如A需要调用B,C,D服务,只有B,C,D服务都走完,A服务才能完成。
扇出:当前模块直接调用下级模块的个数。
如果扇出的链路上某个服务调用响应时间过长或不可用,对当前模块的调用就会占用越来越多的资源,甚至造成系统崩溃。这就是所谓的系统雪崩效应。
一个高流量的应用,单一的后端依赖可能导致所有服务器上的所有资源在很快时间内饱和,更糟糕的是,应用程序还可能导致服务之间的延迟增加,队列,线程等资源紧张,进而导致整个系统发生更多的故障。
为了避免出现这样的情况,就需要对故障和延迟进行隔离,避免因为某一个服务的问题,拖累其他服务的正常运行。
当一个模块出现问题后,如果这个模块还在接受请求,而且还调用了其他模块,这样就会导致级联故障,导致系统雪崩效应。
2.Hystrix是什么
Hystrix是一个用于处理分布式系统延迟和容错的开源库,在分布式系统里,许多依赖不可避免出现调用失败的情况,常见的超时、程序异常报错等,Hystrix能够保证在一个依赖出现问题的情况下,不会导致整体服务失败,避免了级联故障,从而提高分布式系统的弹性。
“断路器”本身是一种开关装置,当某个服务发生故障的时候之后,通过断路器的故障监控(类似于保险丝熔断),向调用方返回一个符合预期的、可以处理的备选响应(FallBack),而不是长时间的等待或者抛出调用方无法处理的异常,这样就保证了服务调用方的线程不会长时间、不必要地占用,从而避免了故障在分布式系统中的蔓延,乃至雪崩。
3.Hystrix能做什么
服务降级、服务熔断、接近实时的监控(服务限流)。
4.Hystrix官网
https://github.com/Netflix/Hystrix/wiki/How-To-Use
从https://github.com/Netflix/Hystrix的Hystrix Status的信息可知,Hystrix目前不再进行开发了,从github的更新来看,已经好久没有更新了,Hystrix推荐使用Resilience4j来替代,不过,国内使用Resilience4j的大厂比较少,更多的大厂使用的是Spring Cloud Alibaba Sentinel来实现熔断与限流,又或者在现有的开源框架上进行包装,自己实现功能。
虽然Hystrix不再更新,但是Hystrix的设计理念值得学习,也为后面学习Spring Cloud Alibaba Sentinel做好铺垫。
2.Hystrix重要概念
1.服务降级(fallback)
当程序出现异常、超时、服务熔断、线程池、信号量已满的情况,会发生服务降级,此时服务会返回一个友好的提示,请稍后再试,不让客户端一直等待并立刻返回一个有好的提示。
2.服务熔断(break)
当服务的请求量达到一定限度的时候,可以发生服务熔断,类似于家里的保险丝在大电流的时候,会触发熔断,此时服务直接不可访问,后续可以走服务降级的方式立刻给客户端返回响应。
3.服务限流(flowlimit)
常用在某一时刻的高并发请求,比如秒杀阶段,为了不把服务打死,会将某些请求进行限流,比如放进队列,让其暂时等待。
3.Hystrix案例
1.服务降级(fallback)项目创建
服务降级的原因:程序运行异常、超时、服务熔断触发服务降级、线程池/信号量打满也会导致服务降级
1.1 创建带降级机制的pay生产者模块 (8007)
先把cloud-eureka-server7001和cloud-eureka-server7002改成单机版,后序启动会快一些,修改defaultZone的值为指向自己服务的地址,而不是互相注册的方式。
新建cloud-provider-hystrix-payment8007模块,修改pom.xml,这里加入spring-cloud-starter-netflix-hystrix依赖。
pom 8007文件引入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>
<groupId>org.example</groupId>
<artifactId>cloud-provider-hystrix-payment8007</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<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.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>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>
yaml 8007配置文件
server:
port: 8007
spring:
application:
name: cloud-provider-hystrix-payment
eureka:
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka #集群版
instance:
instance-id: hystrix-payment8007
prefer-ip-address: true #访问路径可以显示IP地址
创建8007主启动类。
package com.atguigu.springcloud;
@SpringBootApplication
@EnableEurekaClient
public class PaymentHystrixMain8007 {
public static void main(String[] args) {
SpringApplication.run(PaymentHystrixMain8007.class, args);
}
}
创建8007业务类(Service和Controller)
service
package com.atguigu.springcloud.service;
@Service
public class PaymentService {
public String paymentInfo_OK(Integer id) {
return "线程池:" + Thread.currentThread().getName() + "\tpaymentInfo_OK, id=" + id;
}
//该方法是测试服务熔断
public String paymentInfo_TimeOut(Integer id) throws InterruptedException {
int time = 3000;
Thread.sleep(time);
return "线程池:" + Thread.currentThread().getName() + "\tpaymentInfo_TimeOut, id=" + id + "\t耗时:" + time;
}
}
controller
package com.atguigu.springcloud.controller;
@RestController
@Slf4j
public class PaymentController {
@Resource
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) throws InterruptedException {
String result = paymentService.paymentInfo_TimeOut(id);
log.info("result={}", result);
return result;
}
}
使用高并发测试工具Apache Jmeter进行测试。
在测试计划上右键→添加→线程(用户)→线程组,添加一个线程组,命名为Spring Cloud,线程数为200,Ramp-Up时间为1,循环次数为100,其余参数保持默认即可,保存线程组。在Spring Cloud线程组上右键→添加→取样器→HTTP请求,命名cloud-provider-hystrix-payment8007,服务器名称或IP为localhost,端口号为8007,HTTP请求为GET请求,路径为http://localhost:8007/payment/hystrix/timeout/1,点击保存,先试试这个超时的请求。点击菜单栏里的绿色箭头发起请求。此时,再通过浏览器访问http://localhost:8007/payment/hystrix/ok/1会发现,也被拖慢了。
此时使用压测工具,并发20000个请求,请求会延迟的那个方法,
压测中,发现,另外一个方法并没有被压测,但是我们访问它时,却需要等待
这就是因为被压测的方法它占用了服务器大部分资源,导致其他请求也变慢了
1.2 创建带降级的order消费者80模块(配置OpenFeign负载均衡)
新建cloud-consumer-feign-hystrix-order80模块,修改pom.xml。
<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.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
yaml配置文件 80
server:
port: 80
# 这里只把feign做客户端用,不注册进eureka
eureka:
client:
# 表示是否将自己注册进EurekaServer默认为true
register-with-eureka: false
service-url:
defaultZone: http://eureka7001.com:7001/eureka/
spring:
application:
name: cloud-consumer-feign-hystrix-order
主启动类 80
通过OpenFeign去调用生产者模块
package com.atguigu.springcloud;
@SpringBootApplication
@EnableFeignClients
public class OrderHystrixMain80 {
public static void main(String[] args) {
SpringApplication.run(OrderHystrixMain80.class, args);
}
}
远程调用pay模块的接口(80)
添加业务类(Service和Controller)。
Service 80 PaymentHystrixService
这个接口是OpenFeign需要配置的,用在消费者端80,为了负载均衡调用生产者端,替换了原先的Ribbon+RestTemplate负载均衡调用
package com.atguigu.springcloud.service;
@FeignClient(value = "CLOUD-PROVIDER-HYSTRIX-PAYMENT")
public interface PaymentHystrixService {
@GetMapping("/payment/hystrix/ok/{id}")
public String paymentInfo_OK(@PathVariable("id") Integer id);
@GetMapping("/payment/hystrix/timeout/{id}")
public String paymentInfo_TimeOut(@PathVariable("id") Integer id) throws InterruptedException;
}
Controller 80
package com.atguigu.springcloud.controller;
@RestController
public class OrderHystrixController {
@Resource
PaymentHystrixService paymentHystrixService;
@GetMapping("/consumer/payment/hystrix/ok/{id}")
public String paymentInfo_OK(@PathVariable("id") Integer id) {
return paymentHystrixService.paymentInfo_OK(id);
}
@GetMapping("/consumer/payment/hystrix/timeout/{id}")
public String paymentInfo_TimeOut(@PathVariable("id") Integer id) throws InterruptedException {
return paymentHystrixService.paymentInfo_TimeOut(id);
}
}
先后启动cloud-eureka-server7001,cloud-provider-hystrix-payment8001,cloud-consumer-feign-hystrix-order80模块。
浏览器访问http://localhost:8001/payment/hystrix/ok/1
、http://localhost:8001/payment/hystrix/timeout/1
、http://localhost/consumer/payment/hystrix/ok/1
都可以正常访问,当访问http://localhost/consumer/payment/hystrix/timeout/1
提示超时了,这是因为Feign的原因,Feign默认连接超时为1秒,默认读取资源超时是1秒,这个暂且先不管,当然,也可以根据前一篇OpenFeign的笔记,修改超时时间。
这时候启动Apache JMeter,向http://localhost:8001/payment/hystrix/timeout/1
请求发送高并发访问,通过浏览器访问http://localhost/consumer/payment/hystrix/ok/1
,会发现直接超时了,此时模拟的情况就是:大量的请求打到生产者上,此时,通过Feign再来一个外部请求,就会出现超时,在不跑压测的时候,这个请求http://localhost/consumer/payment/hystrix/ok/1的响应时间还是很快速的。
原因:8001服务接口被大量请求占用,处理速度跟不上,Tomcat的工作线程已经占满了,后来到的线程只能等待,这就导致浏览器访问本该立刻返回的请求http://localhost/consumer/payment/hystrix/ok/1出现了超时的现象。
真是因为有这种故障或者不佳的情况出现,我们才需要降级、容错、限流等技术来处理这个问题。
- 生产者8001超时了,消费者80不能一直等待,必须有服务降级
- 生产者8001宕机了,消费者80不能一直等待,必须有服务降级
- 生产者8001正常,消费者80自身故障或要求等待时间小于生产者处理时间,消费者80自己处理服务降级
解决:
1.3 配置服务降级(生产者和消费者)
1. 修改pay生产者模块(8007),进行服务降级
(1)为service的指定方法(会延迟的方法)添加@HystrixCommand注解和@HystrixProperty属性注解
(2)主启动类上,添加激活@EnableCircuitBreaker
注解激活Hystrix
(3)测试 触发异常
先从服务生产者端改造,找到paymentInfo_TimeOut()方法,因为这个方法的执行之间有点长,我们给它加一个标准,当方法执行不满足标准要求时,就让目标方法快速失败,继而去执行服务降级的方法,不再继续等待目标方法的返回。
PaymentService.java
controller
在主启动类上添加@EnableCircuitBreaker注解开启断路器功能,启动EurekaMain7001和PaymentHystrixMain8001模块,浏览器访问http://localhost:8007/payment/hystrix/timeout/1
进行测试,方法体业务耗时5秒钟,调用方最多就能等3秒钟,当时间超过3秒,还没有返回,直接执行了paymentInfo_TimeOutHandler()服务降级方法,在浏览器端,我们可以看到具体输出。
@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;
}
可以看到,也触发了降级
2. 修改order消费者模块(80),进行服务降级
一般服务降级,都是放在客户端(order模块)
(1)80消费者yaml配置文件
server:
port: 80
eureka:
client:
register-with-eureka: false
service-url:
defaultZone: http://eureka7001.com:7001/eureka/
#添加激活hystrix配置
feign:
hystrix:
enabled: true
(2)主启动类添加注解 @EnableHystrix
激活Hystrix
注意 消费者端这个注解和生产者的注解不一样(生产者主启动类@EnableCircuitBreaker
)
同时消费者端把OpenFeign也激活,方便调用生产端
(3)service:配置负载均衡的接口PaymentHystrixService+@FeignClient(去调用生产者8007端)
@Component
@FeignClient(value = "CLOUD-PROVIDER-HYSTRIX-PAYMENT" ,fallback = PaymentFallbackService.class)
public interface PaymentHystrixService
{
@GetMapping("/payment/hystrix/ok/{id}")
public String paymentInfo_OK(@PathVariable("id") Integer id);
@GetMapping("/payment/hystrix/timeout/{id}")
public String paymentInfo_TimeOut(@PathVariable("id") Integer id);
}
(4)controller
(5)测试
启动服务注册中心7001模块,pay模块,order模块,
注意:,这里pay模块和order模块都开启了服务降级
此时,服务生产者端,timeout()方法服务运行时间是5s,加了服务降级策略后,timeout()方法如果在3s内不能执行完,就执行服务降级方法,服务消费者端的要求更苛刻,消费者最多等2.5s,在2.5s不能返回,就执行降级方法。通过浏览器访问http://localhost/consumer/payment/hystrix/timeout/1
,在Network里观察,发现2秒多点就触发了服务降级方法,这是因为,我们没有设置Ribbon的默认超时时间(建立连接超时1s,读取资源超时1s)是2s,小于HystrixProperty设置的2.5秒,先触发了Ribbon的超时,代码报错,然后触发了降级方法。我们修改application.yml配置文件,修改Ribbon超时时间。
#80模块端
# 设置feign客户端超时时间,OpenFeign默认支持Ribbon
ribbon:
ReadTimeout: 5000 # 建立连接后,读取资源所用时间
ConnectTimeout: 5000 # 建立连接所用时间
此时,再发送http://localhost/consumer/payment/hystrix/timeout/1
请求,通过Network查看时间,发现返回时间是2.5秒多点,此时是HystrixProperty设置的2.5秒起作用了。并且,浏览器输出的信息是客户端中降级方法的输出。
再来演示一个情况,将客户端HystrixProperty的时间改成3.5s,一般也不会这么设置,因为客户端的3.5s都大于服务端的3s了,这里仅仅做一个测试使用,通过了浏览器访问http://localhost/consumer/payment/hystrix/timeout/1
,观察Network的时间,3s就返回了,而且浏览器展现的内容,是服务端降级方法的输出。
这个地方的超时时间有点乱,我感觉可以这么理解,看这几个超时时间,以超时时间最小的为标准,只要达到最小的超时时间,就会引起服务降级,服务降级的引起是由最小的超时时间决定的。
服务降级加在生产者的时候,直接调用服务生产者,是生产者Controller中HystrixProperty的3s触发降级。
服务降级加在消费者的时候,直接调用服务消费者(复杂)
- 如果没有修改过Ribbon的默认超时,并且消费者调用超过默认的2s,此时,触发服务降级的是min(Ribbon的2s,消费者HystrixProperty指定的时间),谁的值小,就是由谁引发的服务降级。
- 如果修改过Ribbon的默认超时,这里假设修改的值非常大,排除Ribbon调用超时引起的服务降级问题,那么,服务降级的触发条件是消费者HystrixProperty指定的时间,如果此时服务生产者也在HystrixProperty中指定了时间,那么以min(消费者HystrixProperty指定的时间,生产者HystrixProperty指定的时间)作为降级时间,哪个值小,就是由哪个触发的降级,从而走哪个降级方法。
1.4 全局服务降级(降级耦合性)
回头看一下配置过的服务降级方法,如果有10个方法需要服务降级,那么就需要额外配置10个服务降级方法,有没有办法用一个通用的方法处理服务降级,其余的再做自定义配置呢?服务降级方法和业务方法放在一起,导致业务类里混乱不堪,是否可以将降级方法拿出来呢?
上面出现的问题:
1,降级方法与业务方法写在了一块,耦合度高
2.每个业务方法都写了一个降级方法,重复代码多
1. 解决重复代码的问题
配置一个全局的降级方法,所有方法都可以走这个降级方法,至于某些特殊创建,再单独创建方法
(1)在80消费者模块的controller层添加@DefaultProperties(defaultFallback = "paymentGlobalFallbackMethod")
,表明这个类中的所有带@HystrixCommand的方法,如果方法上没有特殊指明,那么,方法发生降级的时候,就走这个paymentGlobalFallbackMethod()全局的降级方法。
(2)使用注解指定其为全局降级方法(默认降级方法)
(3)测试
浏览器访问http://localhost/consumer/payment/hystrix/timeout/1
,依旧可以按照我们指定的超时规则进行服务降级,服务降级时,执行的方法是paymentGlobalFallbackMethod()。
2. 解决代码耦合度的问题(80模块)
修改order80消费者模块,这里开始,pay生产者模块就不服务降级了,服务降级写在order消费者模块即可
为了实现解耦,可以借助@FeignClient注解中的fallback参数。新建一个PaymentFallbackService.java的类,实现PaymentHystrixService接口,重写接口里的方法,这里重写的两个方法,就是用于服务降级执行的方法,最后,将PaymentFallbackService类名,写到@FeignClient注解中的fallback参数上即可完成业务方法与降级方法解耦的效果。
(1)PaymentHystrixService接口是远程调用pay模块的
在该接口中添加fallback属性,将服务降级方法所在类指定为该接口的实现类
@FeignClient(value = "CLOUD-PROVIDER-HYSTRIX-PAYMENT", fallback = PaymentFallbackService.class)//PaymentFallbackService该服务降级方法所在类指定为这个接口的实现类
public interface PaymentHystrixService {
@GetMapping("/payment/hystrix/ok/{id}")
public String paymentInfo_OK(@PathVariable("id") Integer id);
@GetMapping("/payment/hystrix/timeout/{id}")
public String paymentInfo_TimeOut(@PathVariable("id") Integer id) throws InterruptedException;
}
(2) PaymentFallbackService去实现PaymentHystrixService接口重写接口中的方法,这个重写的方法就是用于服务降级执行的方法
/**
* 当PaymentHystrixService里的调用出错了,会执行这里对应的方法,从而把业务方法和降级方法解耦
*/
@Component
public class PaymentFallbackService implements PaymentHystrixService {
@Override
public String paymentInfo_OK(Integer id) {
return "paymentInfo_OK()方法对应的降级方法";
}
@Override
public String paymentInfo_TimeOut(Integer id) throws InterruptedException {
return "paymentInfo_TimeOut()方法对应的降级方法";
}
}
(3)修改yaml配置文件(80模块)
它的运行逻辑是:
当请求过来,首先还是通过Feign远程调用pay模块对应的方法
但是如果pay模块报错,调用失败,那么就会调用服务降级的方法 ---- PaymentFallbackService类的
当前重写的同名的方法,作为降级方法
当8007服务提供者宕机后,只有消费者请求访问时,直接走降级
2. 使用服务熔断
当服务的请求量达到一定限度的时候,可以发生服务熔断。
比如并发达到1000,我们就拒绝其他用户访问,在有用户访问,就访问降级方法
1,修改前面的pay模块8007
1. 修改8007生产者Payservice接口,添加服务熔断相关的方法
这里属性整体意思是:
10秒之内(窗口,会移动),如果并发超过10个,或者10个并发中,失败了6个,就开启熔断器
IdUtil是Hutool包下的类,这个Hutool就是整合了所有的常用方法,比如UUID,反射,IO流等工具方法什么的都整合了
断路器的打开和关闭,是按照一下5步决定的
1,并发此时是否达到我们指定的阈值
2,错误百分比,比如我们配置了60%,那么如果并发请求中,10次有6次是失败的,就开启断路器
3,上面的条件符合,断路器改变状态为open(开启)
4,这个服务的断路器开启,所有请求无法访问
5,在我们的时间窗口期,期间,尝试让一些请求通过(半开状态),如果请求还是失败,证明断路器还是开启状态,服务没有恢复
如果请求成功了,证明服务已经恢复,断路器状态变为close关闭状态
2,修改controller
添加一个测试方法;
3,测试:
启动pay,order模块
多次访问,并且错误率超过60%:
此时服务熔断,此时即使访问正确的也会报错:
但是,当过了几秒后,又恢复了
因为在10秒窗口期内,它自己会尝试接收部分请求,发现服务可以正常调用,慢慢的当错误率低于60%,取消熔断
2. Hystrix所有可配置的属性
全部在这个方法中记录,以成员变量的形式记录,
以后需要什么属性,查看这个类即可
3. 总结
当断路器开启后:
其他参数:
熔断整体流程:
1请求进来,首先查询缓存,如果缓存有,直接返回
如果缓存没有,--->2
2,查看断路器是否开启,如果开启的,Hystrix直接将请求转发到降级返回,然后返回
如果断路器是关闭的,
判断线程池等资源是否已经满了,如果已经满了
也会走降级方法
如果资源没有满,判断我们使用的什么类型的Hystrix,决定调用构造方法还是run方法
然后处理请求
然后Hystrix将本次请求的结果信息汇报给断路器,因为断路器此时可能是开启的
(因为断路器开启也是可以接收请求的)
断路器收到信息,判断是否符合开启或关闭断路器的条件,
如果本次请求处理失败,又会进入降级方法
如果处理成功,判断处理是否超时,如果超时了,也进入降级方法
最后,没有超时,则本次请求处理成功,将结果返回给controller
4. Hystrix服务监控
1.HystrixDashboard
2 . 使用HystrixDashboard
1. 创建9001服务监控项目
新建cloud-consumer-hystrix-dashboard9001模块,修改pom.xml,引入了spring-cloud-starter-netflix-hystrix-dashboard坐标。
(1) pom文件
<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.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<dependency>
(2)配置文件yml
(3)主启动类
2. 修改所有pay模块(8007,8002,8003…)
他们都添加一个pom依赖: actuator监控组件
之前的pom文件中都添加过了,这个是springboot的监控组件
3,启动9001即可
访问: localhost:9001/hystrix
4,注意,此时仅仅是可以访问HystrixDashboard,并不代表已经监控了8001,8002
如果要监控,还需要配置:(8001为例)
8007的pom.xml
添加如下依赖,否则主启动类添加的@Bean方法报红
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
8007的主启动类添加:
其他8002,8003都是一样的
5. 到此,可以启动服务
启动7001,8007,9001
然后在web界面,指定9001要监控8001: