【微服务学习-- 组件】 熔断器Hystrix
一、什么是Hystrix
由于在我们访问页面时,可能会通过服务注册中心,用一个服务去调用另外一个服务,但是可能由于网络原因或者超时访问等情况,导致一个或者一些服务堆积,这样就可能会导致其他服务受到影响甚至崩溃,这种导致服务堆积的现象就被称为雪崩。
为了避免雪崩,Nestrix公司引入了一款防雪崩利器即Hystrix
Hystrix具备服务降级、服务熔断、依赖隔离,监控等功能。
服务降级:当某一请求不可用时,向接收方回复一个可以备选的响应,也就是我们在遇到网络不可达时,会出现,您要访问的页面跑丢了。(注意不是直接出现404,而是委婉的)。
导致服务降级的原因:1.程序发生异常 2.超时 3.服务熔断
二、演示
1.建立Eureka服务注册中心,和普通的一样,就不加以展示。 端口号为9100
2.建立Eureka-client-provider 端口号为:8083
2.1 pom文件和application.yml都和之前的一样
2.2 建立Testcontroller类,模拟在consumer调用provider时,产生异常和超时。
@RestController
public class TestController {
/**
* 这是在演示异常时的服务熔断
* @return
*/
@RequestMapping("/test")
public String test(){
int a=6/0;
return "带有断路器的服务提供者";
}
/*
演示的是超时异常 让该线程休眠200秒 但是 在consumer中进让其休眠2秒
*/
@RequestMapping("/test02")
public String test02(){
try {
Thread.sleep(200000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "带有熔断器的服务提供者";
}
3.建立Eureka_client_consumer模块,模拟消费者,会调用provider的注册的方法,模拟A服务调用B服务的过程。 端口号为 8086
3.1 pom文件中引入Hystri依赖
<!--添加断路器的依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
3.2 配置application.properties文件 开启健康检查
server.port=8086
spring.application.name=0704-pm-spring-cloud-hystrix-eureka-client-consumer
eureka.client.service-url.defaultZone=http://localhost:9100/eureka
#开启健康检查
management.endpoints.web.exposure.include=hystrix.stream
3.3 创建配置类 RestTemplateConfig:
RestTemplate是一个用于进行HTTP请求的客户端工具,简化了Java程序中进行RESTful服务的调用过程。它是由spring-boot-starter-web引入的。
@Configuration
public class RestTemplateConfig {
@Bean
@LoadBalanced //负载均衡
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
3.4 加入熔断的处理类:MyHystrixCommand该类继承了HystrixCommand类 请注意这个类,之后将使用该类模拟现象。
public class MyHystrixCommand extends HystrixCommand<String> {
//请求对象
private RestTemplate restTemplate;
//请求的地址
private String url;
public MyHystrixCommand(Setter setter,RestTemplate restTemplate,String url){
super(setter);
this.restTemplate=restTemplate;
this.url=url;
}
/**
* 这个方法可以重写但是不能被手动调用
* @return
* @throws Exception
*/
@Override
protected String run() throws Exception {
return restTemplate.getForObject(url,String.class);
}
/**
* Fallback逻辑是在服务调用未能成功返回结果时执行的替代逻辑。
* 它可以是一个预定义的默认值、一个备用的服务调用,
* 或者其他的错误处理逻辑,
* 以确保客户端能够得到一个合理的响应,
* 而不会被异常中断。
* @return
*/
@Override
public String getFallback() {
return "error";//该方法就是我们要在控制器中定义的方法
}
}
该类的作用是封装了需要保护的代码逻辑,实现对服务的熔断、降级和隔离。
其中需要重写其中的run方法和fallback方法,run方法中定义的是需要进行熔断保护的逻辑
fallback方法定义的是需要回退的代码逻辑。其中的返回值类型是String类型的,也就是我们需要定义在controller中的代码逻辑名。
3.5 定义controller类 也是测试用例,在其中需要调用到来自provider的方法,来模拟服务调用过程,注意,此时在provider中添加的有异常和超时两种类型的错误。
@RestController
public class TestController {
@Autowired
private RestTemplate restTemplate;
/*
该方法是访问的controller的test01,但是在其中调用的是provider的test,如果中间出现错误
异常或者是超超时, 就会调用fallback中的熔断方法
*/
@HystrixCommand(fallbackMethod = "error")
@RequestMapping("/test")
public String test(){
ResponseEntity<String> result = restTemplate.getForEntity("http://localhost:8083/0704-pm-spring-cloud-hystrix-eureka-client-provider/test", String.class);
String body = result.getBody();
return "这里是在consumer中调用了,使用了hystrix的服务";
}
@HystrixCommand(fallbackMethod = "error",commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds" ,value = "2000")
})
@RequestMapping("/test02")
public String test02(){
ResponseEntity<String> result = restTemplate.getForEntity("http://localhost:8083/0704-pm-spring-cloud-hystrix-eureka-client-provider/test02", String.class);
String body = result.getBody();
return "这里是在consumer中调用了,使用了hystrix的服务+"+body;
}
//断路器中的方法:
public String error(Throwable throwable){
System.out.println("********"+throwable.getClass());
System.out.println("++++++++++"+throwable.getMessage());
return "服务熔断了......";
}
}
带背景颜色的 是我们在添加断路器之后的方法。
3.6 在启动类 贴标签 开启短路检查:
@SpringBootApplication
@EnableEurekaClient
@EnableCircuitBreaker
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
开启服务,此时演示的是没有3.4的断路器以及3.5中的没有带背景颜色的情况。
4.测试
4.1 访问:http://localhost:9100/ 查看eureka注册情况:
可以看到provider已经注册成功。
4.2 此时访问http://localhost:8083/test
可以看到页面提示报错了那么我们再看控制台:
所以是我们当时建的那个6/0报错了,导致的异常
4.3开启consumer
访问http://localhost:9100/ 查看eureka注册情况:
注册成功
4.4访问 localhost:8086/test 因为此时没有加熔断器
报错了 ,说明中间的跳转时,可能会有异常或者是超时的情况。
4.5 将上边带有 背景颜色的代码进行接触 再进行演示。
4.6访问:localhost:8086/test
可以看到 页面显示的是我在控制器中定义的error(在熔断器中,getFallback返回值名字一致的方法)。
我们再去观察控制器的输出信息,因为我在controller的error方法中,我对错误信息进行了输出:
这个是在provider的报错信息
这个是在consumer中的报错信息
访问一下超时的情况: 访问:localhost:8086/test02
看一下控制台的报错信息:
因此 可以得出结论 熔断器可以起到降级服务扽作用。
三、在熔断器的基础上加上仪表盘dashboard
在第二步的基础上进行展开。
5 .修改consumer的项目:
5.1 在consumer的项目中添加依赖:
<!-- 健康的服务监控 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
5.2 在consumer的配置文件中 开启健康检查 上边已经开启:
server.port=8086
spring.application.name=0704-pm-spring-cloud-hystrix-eureka-client-consumer
eureka.client.service-url.defaultZone=http://localhost:9100/eureka
#开启健康检查
management.endpoints.web.exposure.include=hystrix.stream
6 、建立 client-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-web</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-starter-test</artifactId>
<scope>test</scope>
</dependency>
6.2 配置配置类:
server.port=2021 # 只配置一个端口号
6.3 设置 启动类 添加开启仪表盘的标签:
@SpringBootApplication
@EnableHystrixDashboard
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
7.测试:
一次开启Eureka-Server---> Eureka-Client-Provider --->Eureka-Client-Consumer ---> Eureka-Hystrix ----> Eureka-Dasshboard
7.1 访问:http://localhost:9100/ 查看eureka注册情况:
7.2 访问: http://localhost:8086/actuator/hystrix.stream
因为此时没有访问接口,在页面中,会一直出现ping命令,因为此时,没有访问任何一个可能会有发生熔断的接口,因此会出现ping来表示正在进行健康检查的情况。
7.3 先访问 http://localhost:8086/test 出发熔断命令后,在访问http://localhost:8086/actuator/hystrix.stream:
出现的是json格式的数据。
7.4 访问 Hystrix Dashboard 可以直观的看到数据变化情况,
提交之后就会出现: