分布式系统中,服务与服务之间的依赖错综复杂,不可避免,其中一些服务会出现故障 ,导致依赖他们的其他服务出现远程调度的线程问题(雪崩效应)。而Hystrix提供的熔断器,通过隔离服务的访问点,能阻止这种分布式系统中出现的联动故障,并提供故障的解决方案,从而提高了整个分布式系统的弹性。
什么是Hystrix
Hystrix是Netflix公司的开源项目,它提供熔断器功能,能够阻止分布式系统中出现联动故障。Hystrix是通过隔离服务的访问点阻止联动故障的,并提供故障的解决方案,从而提高整个分布式系统的弹性
Hystrix设计原则
- 防止单个服务的故障耗尽整个servlet的资源
- 快速失败机制,如果某个服务出现故障,则调用该服务的请求快速失败,而不是等待
- 提供回退方案fallback,请求故障时,提供设计好的回退方案
- 使用熔断机制,防止扩散到其他服务去
- 提供熔断器的监控机制Hystrix Dashboard,可以实时监控熔断器状态
工作机制
- 当某个API接口失败的次数在一定时间内小于设定的阀值时,熔断器处于关闭状态,该API正常提供服务。
- 当失败次数大于设定的阀值的时候,Hystrix判定改API接口出现故障,打开熔断器,这时候该请求API接口会执行快速失败的逻辑(fallback回退的逻辑)而不执行业务逻辑,请求的线程不会处于阻塞状态。
- 处于打开状态的熔断器,一段时间后会处于半打开状态,并将一定数量的请求执行业务逻辑,剩余的请求会执行快速失败。若执行的业务逻辑请求失败,则熔断器继续打开,若成功则熔断器关闭。
RestTemplate+Ribbon上使用熔断器
- 引入依赖starter-hystrix后,在启动类加上@EnableHystrix注解就可以开启熔断器功能
- 在方法上添加@HystrixCommand注解,设置fallBackMethod属性,指定fallback回调,最好返回一些静态字符串,不需要处理复杂逻辑什么的,这样可以方便执行快速失败,释放线程资源。
小demo(注:代码接微服务之Sring Cloud使用Feign实现负载均衡&Feign简介一期博客:
基本步骤:
- 创建Hystrix模块
- 配置pom.xml
- 创建application.yml配置文件
- 创建ProductClientService接口、ProductClientServiceImpl实现类
- 创建ProductMapper接口
- 创建ProductController类
- 配置mybatis
- 创建ProductProvider_8002_hystrix主启动类
- 测试
细节实现:
1. 创建名为microService-provider-hystrix-8002的Maven项目
2. 配置pom.xml文件
<dependencies>
<!--依赖关系-->
<dependency>
<groupId>cn.zf</groupId>
<artifactId>microService-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!--添加Eureka客户端的依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!--springboot web启动器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- mybatis 启动器-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
<!