概述
什么是Hystrix
Hystrix是一个用于处理分布式系统的延迟和容错的开源库,在分布式环境中,许多服务依赖关系不可避免地会失败,比如网络延迟导致的服务超时,服务异常等等。Hystrix能保证某一个服务出问题的情况下,不会导致服务整体失败,避免级联故障,提高分布式系统的弹性。
Hystrix实现了断路器的模式,当某个服务发生故障之后,通过断路器的故障监控,向调用方返回一个符合预期的、可处理的备选方案,而不是长时间的等待或者抛出调用方无法处理的异常,这样就保证了服务调用方的线程不会被长时间、不必要地占用,从而避免了故障在分布式系统中的蔓延,乃至雪崩的发生。
服务熔断
服务熔断就类似于家庭中的保险丝,当调用分布式系统中某一个服务时,在一定的时间内,这个服务发生的故障次数达到一定的条件,就打开断路器,不在继续调用这个服务,而是直接去调用他的降级服务,这时熔断器的状态为Open。
等过了一段时间后,也就是断路器打开之后休眠时间过后,熔断器进入Half-Open,半开状态,这时尝试对被熔断的服务进行调用,如果依然调用失败,熔断器继续进入Open状态,如果调用成功,熔断器进入Closed状态。
服务降级
服务降级是在系统压力过大的情况下,为了预防某些服务出现负荷过载或者响应慢的情况,在其内部暂时舍弃一些非核心的接口和数据的请求,直接向用户返回一个友好的提示,告知用户服务暂时不可用,虽然提供的是一个有损的服务,但却保证了整个系统的稳定性和可用性。
应用实例
我们先感受一哈服务降级
先看服务降级
服务降级有两种解决方案:
1.从服务提供方进行降级 2.从服务消费方进行降级
先看服务提供方降级
提供方还是用eureka集群那篇文章里用的代码,下面进行一些修改
1.引入hystrix依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
<version>2.2.1.RELEASE</version>
</dependency>
2.之前服务提供方是从数据库查询数据,现在我们让它在没有查找到数据的时候抛出异常,如果没有服务降级,系统肯定报错,但是引入了Hystrix后,我们让它在抛出异常后,调用他的fallback方法,向用户进行反馈。
@GetMapping("/dept/{id}")
@HystrixCommand(fallbackMethod = "queryByIdHystrix")) //当服务抛出异常后,调用备用方案
public Dept queryById(@PathVariable("id") int id){
System.out.println("首选方案执行了111");
Dept dept = deptService.queryById(id);
if(dept==null)
throw new RuntimeException("用户不存在");
return dept;
}
/**
* queryById的备用方案
* fallback方法的声名必须和原方法一致
*/
public Dept queryByIdHystrix(@PathVariable("id") int id){
System.out.println("备选方案执行了222");
Dept dept = new Dept();
dept.setDeptno(id);
dept.setDeptname("没有查到");
return dept;
}
3.在启动类上添加注解
@EnableCircuitBreaker
然后启动eureka注册中心,服务提供方和服务消费方
当我们查询数据库中存在的数据时
控制台输出
查询数据库中不存在的数据时
控制台输出:
这是先执行了查询方法,没有找到抛出异常,然后执行了提前写好的fallback方法
然后是服务消费方降级
这里的服务消费方还是feign那篇文章中用的代码,下面对其进行修改
feign的本地接口类DeptConsumerService
@FeignClient(value="SPRINGCLOUD-PROVIDER-DEPT",fallbackFactory = DeptConsumerServiceFallBack.class)
public interface DeptConsumerService {
@GetMapping("/dept/{id}")
public Dept queryById(@PathVariable("id") int id);
@GetMapping("/dept/all")
public List<Dept> queryAll();
@PostMapping("/dept/add")
public boolean addDept(Dept dept);
}
这个接口本来是要向"SPRINGCLOUD-PROVIDER-DEPT"获取服务,但是由于某些原因,比如服务器宕机,或者系统压力过大这个服务被停掉了,就找到DeptConsumerServiceFallBack这个类,由它来提供一个实现编辑好的服务,告知用户服务不可用。
DeptConsumerServiceFallBack类的编写
这个类要实现FallbackFactory接口,接口中有一个create方法需要实现,我们要返回DeptConsumerService对象
public class DeptConsumerServiceFallBack implements FallbackFactory {
public DeptConsumerService create(Throwable throwable) {
return new DeptConsumerService() {
public Dept queryById(int id) {
System.out.println("客户端主动降级");
Dept dept = new Dept();
dept.setDeptname("没有获取到服务,服务降级");
return dept;
}
public List<Dept> queryAll() {
return null;
}
public boolean addDept(Dept dept) {
return false;
}
};
}
}
在application.yml文件中开启服务降级
feign:
hystrix:
enabled: true
其他的地方不用修改,和以前保持一致即可
启动服务
查询服务中存在的数据
查询服务中没有的数据
经过以上两次查询,控制台输出
当我们关闭服务提供者
再次查询
控制台输出
我们可以看到,在服务提供方关闭的情况下,消费方依然可以通过服务降级来给用户进行友好的提示,增强服务的可用性
同时,提供方和消费方同时配置了服务降级,在消费方能正常获取提供方的服务的情况下,调用的是提供方的服务降级,在消费方不能获取提供方的服务时,调用的是消费方的服务降级。
监控页面的配置
新建一个module
导入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
<version>1.4.7.RELEASE</version>
</dependency>
在application.yml中修改端口
server:
port: 9001
创建一个启动类
@SpringBootApplication
@EnableHystrixDashboard
public class DeptDashboard {
public static void main(String[] args) {
SpringApplication.run(DeptDashboard.class,args);
}
}
启动项目,访问 http://localhost:9001/hystrix
就能看到猪猪了(Hystrix --豪猪)
我们要监控服务提供方,所以要对提供方进行配置
引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<version>2.3.3.RELEASE</version>
</dependency>
在application.yml中添加配置
management:
endpoints:
web:
exposure:
include: hystrix.stream
然后就可以启动项目
服务提供方的端口号为8001,在猪猪页面输入地址就可以进行监控
当消费方向提供方发送请求后,就可以在监控页面看到信息
服务熔断
我们刚才已经说了什么是服务熔断,就是当服务发生的故障次数达到一定的条件,就打开断路器,不在继续调用这个服务,而是直接去调用他的降级服务,断路器打开,当一段时间过后,断路器进入半开状态,发现服务恢复正常,再把断路器关闭。
下面我们就来感受一哈。
首先需要对服务提供方进行一些配置,主要对Hystrix进行一些配置
@GetMapping("/dept/{id}")
@HystrixCommand(fallbackMethod = "queryByIdHystrix",commandProperties = {
@HystrixProperty(name="circuitBreaker.enabled",value = "true"),//熔断器在整个统计时间内是否开启
@HystrixProperty(name="circuitBreaker.requestVolumeThreshold",value = "10"), // 至少有10个请求才进行熔断错误比率
// 计算,在一个窗口时间内(默认10秒),只收到收到9个请求,即使这9个请求都失败了,断路器也不会打开
@HystrixProperty(name="circuitBreaker.errorThresholdPercentage",value ="50"),//当出错率超过50%后熔断器启动
@HystrixProperty(name="circuitBreaker.sleepWindowInMilliseconds",value = "10000")//用来设置当断路器打开之后的休眠
// 时间,休眠时间结束之后,会将断路器设置为“半开”状态,尝试请求被熔断的服务,如果服务恢复,就关闭熔断器,否咋继续打开
})
public Dept queryById(@PathVariable("id") int id){
System.out.println("首选方案执行了111");
Dept dept = deptService.queryById(id);
if(dept==null)
throw new RuntimeException("用户不存在");
return dept;
}
/**
* queryById的备用方案
* @return
*/
public Dept queryByIdHystrix(int id){
System.out.println("备选方案执行了222");
Dept dept = new Dept();
dept.setDeptno(id);
dept.setDeptname("没有查到");
return dept;
}
然后启动服务
当我们查询数据库中不存在的数据时
控制台输出
说明先执行了查询方法,然后执行了fallback方法
但是当我们一直提交查询,提交9次,9次都失败,失败率100%,但是断路器依旧是关闭的状态,因为我们设置了circuitBreaker.requestVolumeThreshold,只有在一个窗口时间内,超过10次,才开始计算熔断错误比率
我们这次提交11次,我们看到熔断器已经打开
熔断器打开后,在熔断器休眠时间内,就是我们配置的circuitBreaker.sleepWindowInMilliseconds,无论是查询数据库中存在的数据,还是不存在的数据,查询方法都不会执行,会直接执行fallback方法,查看控制台输出
当休眠时间结束后,如果我们继续查询数据库中不存在的数据,就会抛出异常,那么熔断器就会继续进入打开状态,如果我们查询数据库中存在的数据,就没有异常,那么熔断器就会关闭
就先写这么多吧
最后
以上就是稳重日记本为你收集整理的Hystrix简介与服务熔断,服务降级,Hystrix监控页面的全部内容,希望文章能够帮你解决Hystrix简介与服务熔断,服务降级,Hystrix监控页面所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复