Hystrix 降级处理 和 隔离策略
背景
分布式系统环境下,服务间类似依赖非常常见,一个服务可能以来多个基层服务,当某一个服务出现异常或者线程被阻塞,导致无法对外提供服务,并且这种不可用,可能沿调用链向上传递,这种现象被称为雪崩效应 , Hystrix给我们解决了同步等待的雪崩问题
降级处理
1、导入 spring-cloud-starter-hystrix 依赖包
2、在可能出现异常的方法上添加 @HystrixCommand 注解,注解中添加 fallbackMethod 属性 例如:
@HystrixCommand(fallbackMethod = "kafeihaishihenbucuode")
意思就是:如果这个方法出现异常,就会执行 fallbackMethod 指向的方法,这个方法需要在本类中,除了方法名和原方法不一致之外,其他均一致(修饰符,返回值,参数均需要一致)
降级之后的效果:
当这个方法执行出错的时候,或者请求超过1s 没有进行返回结果,就行执行你写的兜底方法,也就是你写的降级方法
熔断处理
在 10s 内 请求连续失败 20 次, 会自动熔断,熔断后的5秒钟之内,请求会直接执行降级方法,不再执行原来的方法,也就是从熔断后,隔 5秒钟 会尝试执行之前的方法 看看是否可以执行
隔离策略
1、在降级的基础之上,在@HystrixCommand 注解中,添加属性:
commandProperties ={@HystrixProperty(name = "execution.isolation.strategy",value = "SEMAPHORE")
设置*HystrixCommand.run()*的隔离策略,有两种选项:
THREAD —— 在固定大小线程池中,以单独线程执行,并发请求数受限于线程池大小。
SEMAPHORE —— 在调用线程中执行,通过信号量来限制并发量。
默认值:THREAD(ExecutionIsolationStrategy.THREAD)
可选值:THREAD,(线程池)SEMAPHORE(信号量)
隔离之后的效果:
每一个 @HystrixCommend 注解都会生成一个 Hystrix 线程池,也就是添加注解的每个方法都有自己的线程池,将每个操作放在独立的线程池里操作,就可以实现资源的隔离
在大量请求进行访问的时候,默认(Thread)的是 tomcat 线程 通知 Hystrix 的线程池(默认10个线程)去处理 请求,
在设置成(SEMAPHORE)后,转换成 tomcat 线程直接 发起请求,但是有一个信号量,默认拿10 个线程,当线程拿完10个后,就不拿了,这样保证 tomcat中时刻有线程可以拿
@GetMapping("/order/{id}")
@HystrixCommand(fallbackMethod = "kafeihaishihenbucuode",commandProperties ={@HystrixProperty(name = "execution.isolation.strategy",value = "SEMAPHORE")} )
public Order getOrderById(@PathVariable Integer id) {
System.err.println("order收到查询请求了"+Thread.currentThread().getName());
Order order = new Order();
order.setId(id);
order.setAddress("天堂路 666 号 666 楼 666 室");
OrderItem orderItem = itemFeignClient.getItemById(id + 1);
order.setOrderItem(orderItem);
// if (new Random().nextBoolean()) {
// int i = 1 / 0;
// }
int i = 1 / 0;//模拟一直出问题
return order;
}
public Order kafeihaishihenbucuode(Integer id, Throwable throwable) {
System.err.println("order出现异常执行了降级的方法"+Thread.currentThread().getName());
// System.err.println(throwable);
Order order = new Order();
order.setId(-id);
order.setAddress("冤鬼路 444 号 444 楼 444 室");
order.setOrderItem(null);
return order;
}