Hystrix断路器
产生的原因:复杂分布式体系结构中的应用程序有数十个依赖关系,每个依赖关系在某些时候将不可避免地失败。
简介
Hystrix是一个用于处理分布式系统的延迟和容错的开源库,在分布式系统里,许多依赖不可避免的会调用失败,比如超时、异常等,Hystrix能够保证在一个依赖出问题的情况下,不会导致整体服务失败,避免级联故障,以提高分布式系统的弹性。
“断路器”本身是一种开关装置,当某个服务单元发生故障之后,通过断路器的故障监控(类似熔断保险丝),向调用方返回一个符合预期的、可处理的备选响应(FallBack),而不是长时间的等待或者抛出调用方无法处理的异常,这样就保证了服务调用方的线程不会被长时间、不必要地占用,从而避免了故障在分布式系统中的蔓延,乃至雪崩。
官网资料:https://github.com/Netflix/Hystrix/wiki/How-To-Use
Hystrix断路器的功能
服务降级、服务熔断、服务限流
1、服务降级:当服务器压力剧增的情况下,根据当前业务情况及流量对一些服务和页面有策略的降级,以此释放服务器资源以保证核心任务的正常运行
2、服务熔断:熔断这一概念来源于电子工程中的断路器
在互联网系统中,当下游服务因访问压力过大而响应变慢或失败,上游服务为了保护系统整体的可用性,可以暂时切断对下游服务的调用。
3、服务限流:限流主要的作用是保护服务节点或者集群后面的数据节点,防止瞬时流量过大使服务和数据崩溃(如前端缓存大量实效),造成不可用;还可用于平滑请求。
服务降级
服务降级可以作用在客户端和服务端
此方法需要在每一个需要降级的方法上指定处理方法
//fallbackMethod触发降级后调用的方法paymentInfo_TimeOutHandler
@HystrixCommand(fallbackMethod = "paymentInfo_TimeOutHandler",commandProperties = {
//设置为超时模式,(若该方法(paymentInfo_TimeOut)报异常也会触发) @HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value="3000")
})
public String paymentInfo_TimeOut(Integer id)
{
int second = 5;
try { TimeUnit.SECONDS.sleep(second); } catch (InterruptedException e) { e.printStackTrace(); }
return "线程池:"+Thread.currentThread().getName()+"paymentInfo_TimeOut,id:";
}
public String paymentInfo_TimeOutHandler(Integer id){
return "调用支付接口超时或异常:\t"+ "\t当前线程池名字" + Thread.currentThread().getName();
}
}
//主启动类添加注解 因为此项目是微服务项目,肯定需要一些微服务的配置,注册中心,添加pom文件,yml配置等,@EnableEurekaClient
@EnableCircuitBreaker
上述方法显得代码臃肿,每一个方法都需要一个@HystrixCommand
可以在类上加入此注解@DefaultProperties(defaultFallback = "paymentInfo_TimeOutHandler"),并在要开启服务降级的方法上添加@HystrixCommand,如果添加了@HystrixCommand会自动触发降级,当然也可以配合@HystrixCommand(fallbackMethod = "paymentInfo_TimeOutHandler",commandProperties = {
//设置为超时模式,(若该方法(paymentInfo_TimeOut)报异常也会触发) @HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value="3000")
})做精准匹配
上述操作将处理降级与业务逻辑耦合在一起
解决耦合:客户端视同过controller层调用通过@FeignClient标记的service层,我们可以自定义实现类实现该接口,然后再接口上添加fallback =“ ”来指定实现了service层的实现类,这样就可以分离代码了。
@Component
public class PaymentFallbackService implements PaymentFeignClientService
{
@Override
public String getPaymentInfo(Integer id)
{
return "服务调用失败,提示来自:cloud-consumer-feign-order80";
}
}
@Component
@FeignClient(value = "CLOUD-PROVIDER-HYSTRIX-PAYMENT",fallback