Hystrix简介
Hystrix是一个用于处理分布式系统的延迟和容错的开源库,在分布式系统里,许多依赖不可避免的会调用失败,比如超时、异常等,Hystrix能够保证在一个依赖出问题的情况下,不会导致整个服务失败,避免级联故障,以提高分布式系统的弹性。
“断路器”本身是一种开关装置,当某个服务单元发生故障后,通过断路器的故障架空,向调用方返回一个符合预期的。可处理的备选响应,而不是在很长时间等待后抛出调用方无法处理的异常,这样就保证了服务调用方的线程不会被长时间、不必要的占用,从而避免了故障在分布式系统中的蔓延,乃至雪崩。
目前Hystrix已经停止更新。
服务雪崩
多个微服务之间调用的时候,假设微服务A调用微服务B和微服务C,微服务B和C又调用其他的微服务,这就是所谓的“扇出”。如果扇出的链路上某个微服务的调用响应时间过长或者不可用,对微服务A的调用就会占用越来越多的系统资源,进而引起系统的崩溃,这就是所谓的“雪崩效应”。
对于高流量的应用来说,单一的后端依赖可能会导致所有服务器上的所有资源都在几秒钟达到饱和。甚至更糟糕的是,这些应用程序还可能导致服务之间的延迟增加,备份队列,线程和其他系统资源的紧张,导致整个系统发生更多的级联故障。这些否表示需要对故障和延迟进行隔离管理,以便使单个依赖的失败,不能取消整个应用的系统。
服务降级
例如服务器忙,请稍后再试,不让客户端等待,直接返回一个友好提示,fallback。
哪些情况下会出现服务降级?
- 程序运行异常
- 超时
- 服务熔断触发服务降级
- 线程池/信号量打满也会导致服务降级
当我们的服务器压力剧增,为了保证核心功能的可用性,选择降低一些功能的可用性,或者直接关闭其他不必要的功能。
一般而言会独立建立降级系统,可以灵活的配置服务器的降级功能。当然也有用代码自动降级,例如接口超时降级,失败多次重试降级。
降级配置:@HystrixCommand
服务提供者要先从自身找问题,设置自身的超时时间的最大值,如果等待时间小于最大值可以正常运行,如果等于或超过峰值需要有对应的处理方法。
业务类启动:添加@HystrixCommand
@HystrixCommand(fallbackMethod = "paymentInfo_TimeOutHandler", commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1000")
})
public String paymentInfo_TimeOut(Integer id) {
//int age = 10/0;
try {
TimeUnit.MILLISECONDS.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "线程池: " + Thread.currentThread().getName() + " id: " + id + "\t" + "O(∩_∩)O哈哈~" + " 耗时(秒): ";
}
// fallbackMethod指定的方法
public String paymentInfo_TimeOutHandler(Integer id) {
return "线程池: " + Thread.currentThread().getName() + " 8001系统繁忙或者运行报错,请稍后再试,id: " + id + "\t" + "o(╥﹏╥)o";
}
在service实现类上,添加@HystrixCommand
指定fallbackMethod
属性值,该值就是当服务调用超过峰值时,会去调用相对应的方法,这个方法就是fallbackMethod
所指定的方法名,commandProperties = { @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1000") }
设置的是超时情况下,峰值时1000ms,也就是1秒,如果方法处理时间超过1s,那么不会继续执行该方法,转而去执行fallbackMethod指定的方法。
主启动类激活:添加注解@EnableCircuitBreaker
。
@SpringBootApplication
@EnableDiscoveryClient
@EnableCircuitBreaker
public class PaymentHystrixMain8001 {
public static void main(String[] args) {
SpringApplication.run(PaymentHystrixMain8001.class,args);
}
}
通过浏览器访问http://localhost:8001/payment/hystrix/timeout/18
会发现返回的是fallbackMethod指定的方法的返回结果。
那如果处理的方法中,出现了其他异常呢,还会执行fallbackMethod的方法吗?
@HystrixCommand(fallbackMethod = "paymentInfo_TimeOutHandler", commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1000")
})
public String paymentInfo_TimeOut