上文给大家讲解的内容是微服务容错与隔离:熔断保护、超时与重试,那么本文给大家讲解的内容是SpringCloudHystrix容错框架;
Hystrix中文名称为“豪猪”,平时性情温顺,在感受到危险时,用浑身长满的刺来保护自己。Hystrix的整体设计原则是防止单个服务的故障(网络、资源耗尽)等原因产生的分布式下的级联失败,通过快速失败代替队列实现优雅的服务降级,当依赖服务恢复正常后,可快速恢复服务正常运行状态,同时Hystrix提供实时的监控、报警及DashBoard等功能。
Hystrix同样是Netflix开源的一个分布式系统容错框架。在分布式网络环境下,不可避免地出现服务之间因为网络超时、代码异常等原因产生各种各样的调用失效问题,Hystrix通过延迟容忍和错误容忍逻辑可以控制分布式系统之间的交互,在失败调用超过预先设置的阈值时,会自动隔离服务访问、抑制级联错误、支持fallback降级处理等,保证系统的可用性和弹性。
Spring Cloud将Hystrix的容错组件进行了自动化配置,在SpringCloud微服务架构中可以通过注解机制实现Hystrix与不同组件模块的联合使用,实现请求调用的容错处理。
Hystrix的主要特性
● 断路器机制:Hystrix的断路器工作机制非常简单。当HystrixCommand请求后端服务失败数量超过一定比例时(默认为50%),断路器会切换到开路状态(Open),这时所有请求会直接失败而不会发送到后端服务,同时断路器有自我检测并恢复的功能。
● 资源隔离:在Hystrix中,主要通过线程池来实现资源隔离。
通常在使用的时候,我们会根据调用的远程服务划分出多个线程池。如果对性能有严格要求而且确信自己调用服务的客户 端 代 码 不 会 出 问 题 , 可 以 使 用 Hystrix 的 信 号 模 式(Semaphores)来隔离资源。
● 优雅降级:fallback相当于降级操作。对于查询操作,我们可以实现一个fallback方法,当请求后端服务出现异常时,可以使用fallback方法提供返回值。fallback方法的返回值一般是默认值或者来自缓存的值。
● 请求缓存:对于无差异的后端服务请求,我们通常会把第一次请求缓存,对于后面的请求,我们会直接返回第一次请求的缓存作为响应。
Hystrix通常的使用方法
1.使用Hystrix-core的HystrixCommand源码方式
首先,增加Maven配置依赖:
其次,编写业务Command逻辑实现(返回“success”),它继承了HystrixCommand:
最后,调用Hystrix命令类:
2.使用注解@HystrixCommand方式实现熔断及降级管理
首先,加入Maven依赖:
其次,开启Hystrix断路器,使用@EnableHystrix开启SpringBoot对Hystrix的支持:
然后,增加@HystrixCommand注解和fallback方法降级实现。该注解对该方法创建了熔断器的功能,并指定了fallbackMethod熔断方法,熔断方法直接返回一个字符串,字符串为"hi,"+name+",sorry,error!"。
3.在Feign中整合Hystrix
首先,开启Hystrix配置:
其次,使用@EnableFeignClients启动并加载应用:
然后,通过在FeignClient中增加fallback属性,配置连接失败错误的处理类:
最后,创建fallback方法,当访问接口有问题或发生错误时,直接调用此接口:
4.在Zuul网关中使用fallback功能实现熔断降级
Zuul默认提供了对Hystrix的支持,在@EnableZuulProxy注解中,实现代码如下:
在Zuul的HTTP请求源码中,Zuul请求转发会被Hystrix包装成一个Command发送给后端服务,Zuul默认提供了如下请求转发方式:
通过源码可以知道,Zuul将FallbackProvider实例保存在一个Set集合中,并作为
HttpClient-RibbonCommandFactory构造器的参数。
Zuul在转发请求时最终会利用AbstractRibbonCommand进行处理。
AbstractRibbonCommand继承了HystrixCommand,而转发请求的业务逻辑在重写的HystrixCommand类的run方法中,源码如下:
我们知道HystrixCommand提供了getFallback方法,这个方法的作用是当run方法出现异常时自动调用getFallback方法,从而完成降级。由于AbstractRibbonCommand继承了HystrixCommand,它不仅重写了run方法,而且重写了getFallback方法,源码如下:
下面是自定义的ZuulFallbackProvider实现,如果有相应的实现,那么它会直接回调自定义实现类的fallbackResponse方法。
Zuul配置Hystrix时需要注意以下配置信息:
使用Zuul集成Hystrix需要注意:
● Zuul的超时时间要大于等于Hystrix的超时时间,避免Hystrix设置无法生效。
● 在无重试场景下,通过Feign+Ribbon方式进行服务调用时,Hystrix的超时时间要小于Ribbon的超时时间,否则在Ribbon调用其他服务时就已经超时了,Hystrix无法进行熔断及降级。
● 在有重试场景下,如果有组件跟Hystrix配合使用,一般来讲,建议Hystrix的超时时间大于其他组件的超时时间,否则将可能导致重试失效。例如,如果Ribbon的超时时间为1s,
重试3次,Hystrix的超时时间应略大于3s。
Hystrix的服务降级模式
Hystrix通过注解@HystrixCommand可以降低代码的侵入性,下面我们把Hystrix中Command与fallback的常用模式总结一下。
1.同步Command,同步fallback
2.异步Command,同步fallback
3.异步Command,异步fallback
注意:异步fallbackMethod这里必须加@HystrixCommand注解,否则运行时会报错: