Spring Cloud(五) :断路器(Hystrix)
Hystrix是一款Netflix开源的熔断中间件,能够提供熔断,降级,监控等多种服务。就如我们日常生活中的电路保险丝,当接入电源的电器过多,导致整体负载过大时,保险丝会自动熔断,以此保护电器不会受损。而在微服务架构中,当一个服务接口不堪重负,出现超时或宕机等无法使用的情况时,下游服务因获取不到数据,导致服务不可用,然后恶性循环导致整个服务体系宕机,形成雪崩效应。此时熔断器就充当了保险丝的作用..
Hystrix是一款Netflix开源的熔断中间件,能够提供断路,降级,监控等多种服务。
就如我们日常生活中的电路保险丝,当接入电源的电器过多,导致整体负载过大时,保险丝会自动熔断,以此保护电器不会受损。
而在微服务架构中,当一个服务接口不堪重负,出现超时或宕机等无法使用的情况时,下游服务因获取不到数据,导致服务不可用,然后恶性循环导致整个服务体系宕机,形成雪崩效应。此时熔断器就充当了保险丝的作用,在服务接口超时或不可用时,马上返回一个错误信息,让整个服务可以继续运行,保护了整个服务体系。
PS:本文Spring Boot为2.X版本
这里将会在上一篇Spring Cloud(四) :微服务间的互相调用和负载均衡实现(ribbon+restTemplate和feign)
的基础上进一步扩展。
用到的项目为
1.SpringCloudServiceCenter 注册中心
2.SpringCloudConfig 配置中心
3.SpringCloudServiceI 服务I
4.SpringCloudServiceIII 服务III
5.SpringCloudCustomerI ribbon
6.SpringCloudCustomerII feign
服务熔断
一.在ribbon中使用hystrix
SpringCloudCustomerI 基础上扩展
1.添加依赖
<!-- 熔断/降级 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
2.修改MyCustomerController.java。
添加如下内容
添加@HystrixCommand(fallbackMethod = "fallbackInfo")
注解,fallbackMethod
为服务不可用时将会调用的方法
@ResponseBody
@RequestMapping(value="/CgetServiceIData")
@HystrixCommand(fallbackMethod = "fallbackInfo")
public String getServiceIData() {
return getServiceI();
}
String fallbackInfo() {
return "The service is down!";
}
3.启动项SpringCloundCustomerIApplication.java
添加注解。
//两个里选一个即可
@EnableHystrix
@EnableCircuitBreaker
之前看各种博客时总能看到@EnableHystrix
和@EnableCircuitBreaker
交替出现,那么它们有什么区别呢?其实只要点开看一下就知道了。
@EnableHystrix
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@EnableCircuitBreaker
public @interface EnableHystrix {
}
@EnableCircuitBreaker
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(EnableCircuitBreakerImportSelector.class)
public @interface EnableCircuitBreaker {
}
实际上@EnableHystrix其实就是调用的@EnableCircuitBreaker。
4.测试
(1)启动注册中心,配置中心,服务I,服务III,服务消费者I。
查看注册中心http://localhost:8761/
尝试访问http://localhost:8770/CApi/CgetServiceIData
因为服务I和III都启动且没问题,所以输出会以上面的情况交替。
(2)然后我们尝试关闭服务I。
关闭该服务,查看注册中心该服务是否关闭了。
然后尝试访问http://localhost:8770/CApi/CgetServiceIData
会发现一直都是如上输出,从这点看,我这里的ribbon应该默认设置成超时断连了。如果你那边没有设置的话,应该有时会出现The service is down!
内容。
(3)然后尝试下让服务I的服务超时。
修改SpringCloudServiceI项目的ServiceApiController.java中的getInfo方法
添加一个3秒的线程休眠。
@ResponseBody
@RequestMapping(value="/getInfo")
public String getInfo() {
try {
Thread.sleep(3000);//hystrix熔断默认超时时间为2秒,这里模拟超时
} catch (InterruptedException e) {
e.printStackTrace();
}
return "serviceI+"+name;
}
然后启动服务I,查看注册中心
尝试访问http://localhost:8770/CApi/CgetServiceIData
能看到服务III还能正常提供数据,但是服务I会因为超时而返回之前写好的错误信息。
二.在feign中使用hystrix
SpringCloudCustomerII 基础上扩展
1.因为feign中就已经包含了hystrix,所以不需要额外添加依赖,保持原来的即可。
2.如果你使用的Spring Cloud是低版本的话,需要在配置文件application.properties
中添加配置。因为老版本Spring Cloud的话,feign中的hystrix是默认关闭的。
feign.hystrix.enabled=true
3.修改MyCustomerController.java
添加一个服务接口,只获取服务I和服务III的信息
@ResponseBody
@RequestMapping(value="/getServiceIData")
public String getServiceIData(@RequestParam String name) {
String result="";
result+=name+myServiceIService.getInfo();
return result;
}
4.修改MyServiceIService.java接口
因为集成了hystrix,所以可以直接使用fallback来指定访问失败时返回的方法。
并且fallback后填写的类需要实现被填写的接口。即MyServiceIErrorService要实现MyServiceIService
@Component
@FeignClient(value="myServiceI",fallback=MyServiceIErrorService.class)
public interface MyServiceIService {
@ResponseBody
@RequestMapping(value="/myServiceI/Api/getInfo")
public String getInfo();
}
5.添加MyServiceIErrorService.java
实现MyServiceIService
,这样在访问MyServiceIService
的getInfo
方法失败后就会返回MyServiceIErrorService
的getInfo
方法
package com.my.customerII.api;
import org.springframework.stereotype.Component;
@Component
public class MyServiceIErrorService implements MyServiceIService{
public String getInfo() {
return "The Service is down!";
}
}
6.启动测试,什么?你问启动项不用加什么注解吗?确实不用,都集成在@EnableFeignClients
中了_(:з」∠*)_
。
启动服务注册中心,配置中心,服务I,服务III,服务消费者II。
访问注册中心http://localhost:8761/
访问http://localhost:8771/CApi/getServiceIData?name=123
多访问几次,可以看到如下两种输出,因为服务I中的接口故意添加睡眠3S。而hystrix认定超时时间是2S,所以这里在负载均衡到服务I时,就会判断该服务挂掉了,就会返回预设的错误信息。而服务III的接口还是访问正常。
可以试下关闭服务I,结果应该是如上一样。
三.hystrix监控
hystrix可以监控添加了hystrix熔断器接口,并返回访问成功率,访问速度等等。
这里在
1.添加依赖
<!-- hystrix监控 -->
<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-dashboard</artifactId>
</dependency>
2.启动器
添加如下注解SpringCloundCustomerIApplication.java
@EnableHystrixDashboard
然后如果用的是Spring Boot 2.X 版本的话,恭喜,你需要多配置一点东西。
在启动项里加上这个就行了。
registrationBean.addUrlMappings("/hystrix.stream");会影响到之后访问监控
/**
* spring boot 2.X
* @return
*/
@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;
}
3.测试
启动注册中心,配置中心,服务I,服务III,服务消费者I。
访问http://localhost:8770/hystrix
,
如果之前配置的是registrationBean.addUrlMappings("/hystrix.stream")
的话,就在第一个空格中填写http://localhost:8770/hystrix.stream
,title随便填一个值即可,然后点击montor stream按钮。
然后可以看到如下界面,如果出现如下界面,那么表示你用的是Spring Boot 2.X版本了,需要做第2步操作
正常的话是下图
然后新开一个页面访问http://localhost:8770/CApi/CgetServiceIData
几次
再去看刚才的hystrix监控中心,可以看到如下
然后就可以看到服务接口的统计信息了。
更多推荐
所有评论(0)