6、Spring Cloud -熔断器Hystrix
6.1、什么是Hystrix
在分布式系统中、服务与服务之间的依赖错综复杂,一种不可避免的情况就是某些服务
出现故障,导致依赖于它们的其他服务出现远程调度的线程阻塞。
Hystrix是Netflix 公司开源的一个项目,它提供了熔断器功能,
能够阻止分布式系统中出现联动故障
Hystrix 是通过隔离服务的访问点阻止联动故障的,并提供了故障的解决方案,从而提高了
整个分布式系统的弹性
6.2、Hystrix解决了什么问题
在复杂的分布式系统中,可能有几十个服务相互依赖,这些服务由于某些原因:
机房的不可靠性、网络服务商的不可靠性 ,导致某个服务不可用等
如果系统不隔离该不可用的服务,可能会导致整个系统不可用
对于依赖 30 个服务的应用程序,每个服务的正常运行时间为 99.99%
对于单个服务来说, 99.99% 的可用是非常完美的
99.9930 = 99.7% 的可正常运行时间和 0.3% 的不可用时间,那么 10 亿次请求中有 3000000
次失败,实际的情况可能比这更糟糕。
如果不设计整个系统的韧性,即使所有依赖关系表现良好,单个服务只有 0.01% 的不可用,
由于整个系统的服务相互依赖,最终对整个系统的影响是非常大的
在微服务系统中,一个用户请求可能需要调用几个服务才能完成
在所有的服务都处于可用状态时, 一个用户请求需要调用A、H 、I 、P服务
6.3、Hystrix的设计原则
设计原则如下:
6.4、Hystrix的工作机制
如图:
首先,当服务的某个 API 接口的失败次数
在一定时间内小于设定的阀值时,熔断器处于关闭状态,该 API 接口正常提供服务
当该API 接口处理请求的失败次数大于设定的阀值时, Hystrix 判定该 API 接口出
现了故障,打开熔断器,这时请求该 API 接口会执行快速失败的逻辑(即 fall back
回退的逻辑),不执行业务逻辑,请求的线程不会处于阻塞状态。
处于打开状态的熔断器,一段时间后会处于半打开状态,并将 定数量的请求执行正常逻辑。
剩余的请求会执行快速失败,若执行正常逻辑的请求失败了,则熔断器继续打开,若成功了 ,
则将熔断器关闭。这样熔断器就具有了自我修复的能力。
搭建工程
新建工程:
pom依赖:
<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.cloud</groupId> <artifactId>spring-cloud-starter-netflix-ribbon</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency>
RibbonConfig.java
@Configuration public class RibbonConfig { @Bean @LoadBalanced RestTemplate restTemplate(){ return new RestTemplate(); } }
hystrixService.java
@Service public class hystrixService { @Autowired RestTemplate restTemplate; public String port(){ return restTemplate.getForObject("http://CLINET/port",String.class); } }
hystrixController.java
@RestController public class hystrixController { @Autowired hystrixService hystrixService; @GetMapping("/hi") public String hi(){ return hystrixService.port(); } }
主配置类:
@EnableDiscoveryClient @SpringBootApplication public class HystrixApplication { public static void main(String[] args) { SpringApplication.run(HystrixApplication.class, args); } }
测试时可以成功访问两个client
6.5、在RestTemplate和Ribbon 上使用熔断器
1、首先引入相关的依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
2、主配置类加上@EnzbleHystrix注解开启Hystrix的熔断功能
@EnableDiscoveryClient @SpringBootApplication @EnableHystrix public class HystrixApplication { public static void main(String[] args) { SpringApplication.run(HystrixApplication.class, args); } }
修改hystrixService.java中的方法port()方法
@HystrixCommand注解,port()方法就启用 Hystrix 熔断器的功能
fallbackMethod属性为处理回退逻辑的方法
在熔断器打开的状态下,会执行 fallback 逻辑。
fallback 的逻辑最好是返回一些静态的字符串,不需要处理复杂的逻辑,也不需要远程调度其
他服务,这样方便执行快速失败,释放线程资源
hystrixService.java
@Service public class hystrixService { @Autowired RestTemplate restTemplate; @HystrixCommand(fallbackMethod = "isError") public String port(){ return restTemplate.getForObject("http://CLINET/port",String.class); } public String isError(){ return "request is error!"; } }
在测试中:
关闭服务提供者
观察浏览器会显示:
6.6、在Feign上使用熔断器
Feign 的起步依赖中已经引入了 Hystrix 的依赖
所以在 Feign 中使用 Hystrix 不需要引入任何的依赖
使用之前的工程:
地址:https://www.cnblogs.com/Mrchengs/p/10646137.html
新建一个类:
portHystrix.java
需要实现接口中的方法
@Component public class portHystrix implements EurekaClientFeign { @Override public String port() { return "request is wrong!!"; } }
portHystrix作为容器的逻辑处理类,需要实现EurekaClientFeign接口
并在接口中实现方法作为处理熔断逻辑的方法
EurekaClientFeign.java
@FeignClient(value = "CLINET",configuration = feignconfig.class, fallback = portHystrix.class) public interface EurekaClientFeign { @GetMapping("/port") String port(); }
在@FeignClient 注解的fallback 配置加上快速失败的处理类
该 理类是作为 Feign 熔断器的逻辑处理类
必须实现被@FeignClient 修饰的接口。
配置文件中:
spring.application.name=feign server.port=8088 eureka.client.service-url.defaultZone=http://localhost:8762/eureka/ #开启Hystrix的功能 feign.hystrix.enabled=true
正常开启:
此时可以进行访问!!!
6.7、使用Hystrix Dashboard监控熔断器的状态
微服务架构中 ,为了保证服务实例的可用性,防止服务实例出现故障导致线程阻塞
出现了熔断器模型。
烙断器的状况反映了一个程序的可用性和健壮性,它是一个重要指标
Hystrix Dashboard 是监控 Hystrix 的熔断器状况的一个组件,提供了数据监控和 友好的图形化
展示界面。
6.7.1、在RestTemplate中使用Hystrix Dashboard
添加所需要的依赖:
<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-hystrix-dashboard</artifactId> </dependency>
在主配置类中:
开启Hystrix Dashboard 的功能
@EnableCircuitBreaker @EnableHystrixDashboard @EnableDiscoveryClient @SpringBootApplication @EnableHystrix public class HystrixApplication { public static void main(String[] args) { SpringApplication.run(HystrixApplication.class, args); } @Bean public ServletRegistrationBean getServlet(){ HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet(); ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet); registrationBean.setLoadOnStartup(1); registrationBean.addUrlMappings("/actuator/hystrix.stream"); registrationBean.setName("HystrixMetricsStreamServlet"); return registrationBean; } }
坑位......
此时把服务提供者和注册中心均开启:
浏览器上输入:
会一直进行刷新
当访问:
在观察:
数据指标图:会一直刷新
浏览器访问:
此时发现:
在该页面显示了熔断器的各种数据指标
6.7.2、Feign 中使用 Hystrix Dashboard
1、pom文件
<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.cloud</groupId> <artifactId>spring-cloud-starter-netflix-ribbon</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </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-hystrix-dashboard</artifactId> </dependency>
主配置类:
@EnableHystrix @EnableHystrixDashboard @EnableFeignClients(basePackages = "com.cr.eurekafeignclient.feign") @EnableDiscoveryClient @SpringBootApplication public class EurekaFeignClientApplication { public static void main(String[] args) { SpringApplication.run(EurekaFeignClientApplication.class, args); } @Bean public ServletRegistrationBean getServlet(){ HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet(); ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet); registrationBean.setLoadOnStartup(1); registrationBean.addUrlMappings("/actuator/hystrix.stream"); registrationBean.setName("HystrixMetricsStreamServlet"); return registrationBean; } }
其余的测试都和之前相似