目录
1. hystrix
简介
hystrix
是 netlifx
开源的一款容错框架,防雪崩利器,具备服务降级,服务熔断,依赖隔离,监控 hystrix dashboard
等功能,从而提升系统的可用性和容错性
官方 github
:https://github.com/Netflix/Hystrix/wiki/How-To-Use
2. hystrix
容错机制的特点
要防止雪崩效应,必须有一个强大的容错机制。该容错机制需实现以下两点:
- 包裹请求:使用
HystrixCommand
包裹对依赖的调用逻辑,每个命令在独立线程中执行 - 断路器(跳闸)机制:当某服务的错误率超过一定阈值时,
hystrix
可以自动或者手动跳闸,停止请求该服务一段时间 - 资源隔离:
hystrix
为每个依赖都维护了一个小型的线程池(或者信号量)。如果该线程池已满,发往该依赖的请求就被立即拒绝,而不是排队等候,从而加速失败判定 - 回退机制:当请求失败、超时、被拒绝,或当断路器打开时,执行回退逻辑
- 自我修复:断路器打开一段时间后,会自动进入半开状态
2.1. hystrix
的断路器工作原理
- 当请求达到阈值时候:默认
10
秒内20
次请求,当请求失败率达到50%
时,此时断路器将会开启,所有的请求都不会执行 - 断路器开启
5
秒(默认)时,这时断路器是半开状态, 会允许其中一个请求执行 - 如果执行成功,则断路器会关闭;如果失败,则继续开启。循环重复这两个流程
3. hystrix
实现服务的隔离、熔断、降级
继续使用 上一篇 文章中的项目,稍加改造即可实现 hystrix
功能
3.1. Maven
依赖
eureka-client-consumer
消费方项目添加如下依赖
<!--springcloud hystrix-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
3.2. application.properties
配置文件
server.port=8090
#注册进eureka的名称
spring.application.name=eureka-client-consumer
eureka.client.service-url.defaultZone=http://eureka7001:8761/eureka/
eureka.instance.prefer-ip-address=true
#Feign默认整合了Hystrix,要想为Feign打开Hystrix支持,需要此项设置
#在springcloud Dalston之前的版本中,Feign默认开启Hystrix支持,无需设置feign.hystrix.enabled=true
#从springcloud Dalston版本开始,Feign的Hystrix支持默认关闭,需要手动设置开启
feign.hystrix.enabled=true
#配置ribbon的超时时间,默认二者都是1000
#ribbon.ConnectTimeout=2000
#ribbon.ReadTimeout=2000
#第一次启动项目时,请求接口查询数据库有点耗时,会进入降级策略,所以将hystrix的超时时间设置为3s,默认是1s,这是全局设置
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=3000
3.3. 服务消费方主启动类
服务提供方的保持不变,消费方主启动类一定要标注注解 @EnableHystrix
@EnableHystrix
@EnableFeignClients
@EnableEurekaClient
@Slf4j
@SpringBootApplication
public class AppConsumer {
public static void main(String[] args) {
SpringApplication.run(AppConsumer.class, args);
log.info("------AppConsumer Running------");
}
}
3.4. 服务降级的实现
在 feign
整合 hystrix
的情况下,服务降级的实现主要有以下 3
种方式。主要变动的代码都在消费方。当服务调用失败(程序异常,线程池 / 信号量已满,服务下线)或超时了,再或者服务熔断触发了服务降级,这些情况就让其触发服务降级,从而保证了系统的可用性可靠性,防止了系统的整体缓慢甚至崩溃
3.4.1. 方式一
- 使用
feign
的注解@FeignClient
的属性fallback
指定的降级回退方法 - 如果业务层抛出异常,这种方式对异常处理不友好,会直接将异常抛出给用户,除非主动处理这个异常
@FeignClient(name = "eureka-client-producer", fallback = UserConsumerFeignFallback.class)
public interface UserConsumerFeign {
@GetMapping(path = "/user/selectUserById")
ResultVo selectUserById(@RequestParam(name = "id") Integer id);
}
@Component
public class UserConsumerFeignFallback implements UserConsumerFeign {
@Override
public ResultVo selectUserById(Integer id) {