Hystrix是一个用于处理分布式系统的延迟和容错的开源库。Hystrix主要用于处理分布式系统中复杂多变的服务依赖调用失败、超时、异常等状况,保证一个服务依赖出问题的状况下,提供一个服务预期的、可处理的备选响应(FallBack),避免微服务总体级联故障,以提升分布式系统的弹性。git
Hystrix旨在执行如下操做:github
Hystrix在分布式项目中主要用于处理:spring
首先对应服务熔断咱们要理解“服务雪崩”的概念,服务雪崩是多个微服务之间调用的时候,假设微服务A调用微服务B和微服务C,微服务B和微服务C又调用其它的微服务,这就是所谓的“扇出”。若是扇出的链路上某个微服务的调用响应时间过长或者不可用,对微服务A的调用就会占用愈来愈多的系统资源,进而引发系统崩溃,就是所谓的“雪崩”。数据库
熔断机制是应对雪崩效应的一种微服务链路保护机制。api
当扇出链路的某个微服务不可用或者响应时间太长时,就会经过熔断该节点微服务的调用,快速返回错误的响应信息。当检测到该节点微服务调用响应正常后恢复调用链路。网络
在SpringCloud框架里熔断机制经过Hystrix实现。Hystrix会监控微服务间调用的情况,当失败的调用到必定阈值,缺省是5秒内20次调用失败就会启动熔断机制。熔断机制的注解是@HystrixCommand。mybatis
这里咱们仍是基于咱们以前博客的微服务项目springcloud-provider-dept-8001 服务端 复制一份做为hystrix的微服务项目。app
①添加hystrix pom.xml依赖包:框架
<!--引入hystrix--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix</artifactId> <version>1.4.6.RELEASE</version> </dependency>
②修改application.yml配置,修改了实例名称:分布式
server:
port: 8001
##省略了数据库链接信息与mybatis配置
#eureka的配置,肯定客户端服务注册到eureka服务列表内
eureka:
client:
service-url:
#集群配置
defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
#defaultZone: http://localhost:7001/eureka/
instance:
instance-id: springcloud-provider-dept-hystrix-8001 #修改eureka上默认的服务描述信息
prefer-ip-address: true #访问路径能够显示ip地址
③基于Controller层的调用方法经过id获取Dept用户来作异常断定:
@RestController @RequestMapping("/dept") public class DeptController { @Autowired private DeptService service; @GetMapping("/queryById/{id}") /*@HystrixCommand表示一旦调用服务方法失败并抛出了异常信息以后, 会自动调用@HystrixCommand标注好的fallbackMethod中指定名称的方法*/ @HystrixCommand(fallbackMethod = "processHystrixGet") public Dept queryById(@PathVariable("id") Long id){ Dept dept = service.queryById(id); //模拟当查询不到id或者id信息异常时返回错误异常的提示 if(null == dept){ throw new RuntimeException("id=>" + id + "不存在该用户,或者用户信息没法找到!"); } return dept; }; //熔断备选方法:异常回调信息显示 public Dept processHystrixGet(@PathVariable("id") Long id){ return new Dept() .setDeptno(id) .setDname("id=>" + id + "没有对应的信息,null--@Hystrix") .setDbSource("no this database in MySQL"); } }
④在主启动类上添加对hystrix的熔断机制的支持:
@SpringBootApplication @EnableEurekaClient //在服务启动后自动注册到eureka中 @EnableDiscoveryClient //服务发现 @EnableCircuitBreaker //启用对hystrix的熔断机制的支持 public class DeptProvider8001_Hystrix_App { public static void main(String[] args) { SpringApplication.run(DeptProvider8001_Hystrix_App.class, args); } }
⑤启动Eureka客户端、Hystrix服务端进行访问验证:
访问正常存在的服务id,能返回正常数据:
访问异常不存在的id时,返回fallback方法中的信息:
能够看出,当执行调用某个微服务发生异常时,Hystrix能经过自定义的fallbackMethod作异常的错误返回,快速进行异常熔断机制。
服务熔断是在服务运行的状况下,对于服务内部执行错误的异常状况的一种处理方式。
服务降级是从网站总体的负载考虑,当某个服务在某一时间内承受大量的服务请求,而须要极大的资源消耗,须要关闭当前系统的某些服务,作资源的扩充。牺牲单个服务的运行,当再次访问这单个服务的时候,经过服务降级处理,返回给客户设定的默认缺省值。
至关于弃军保帅,维护的是整个系统的可用性。
服务降级这里从客户端进行实现。
(1)首先在springcloud-api中定义一个降级以后的回调函数类,实现FalllbackFactory接口,接口中实现了对应请求信息的异常处理方法:
@Component //注意不要忘记添加,须要把类加载进Spring容器中才能获取到 public class DeptClientServiceFallbackFactory implements FallbackFactory<DeptClientService> { @Override public DeptClientService create(Throwable throwable) { return new DeptClientService() { @Override public boolean addDept(Dept dept) { return false; } @Override public Dept queryById(Long id) { return new Dept().setDeptno(id).setDname("该ID:" + id + "没有对应的信息,Consumer客户端提供的降级信息,此刻服务provider已经关闭"). setDbSource("no this database in MySQL"); } @Override public List<Dept> queryAll() { return null; } }; } }
(2)对应api接口中使用fallabckFatory去指定调用的是哪一个class实现类:
//value中对应服务提供方的名字 //服务降级:表示DeptClientService当前接口中任何一个方法出了问题:都去找DeptClientServiceFallbackFactory回调处理 @FeignClient(value = "SPRINGCLOUD-PROVIDER-DEPT", fallbackFactory = DeptClientServiceFallbackFactory.class) @Component //注入到容器中 public interface DeptClientService { /** * 接口中的三个方法对应服务提供者的三个方法 * 这里面的接口对应服务提供者的controller接口,名称必须一致,而后接口的Mapping映射url必须一致 * @param dept * @return */ @PostMapping("/dept/add") public boolean addDept(Dept dept); @GetMapping("/dept/queryById/{id}") public Dept queryById(@PathVariable("id") Long id); @GetMapping("/dept/queryAll") public List<Dept> queryAll(); }
(3)基于FeignClinet调用,则须要修改服务提供者中application.yml,开启feign中对hystrix的支持:
#开启降级feign.hystrix支持 feign: hystrix: enabled: true
(4)测试验证:
步骤:启动三个Eureka注册中心700一、700二、7003,启动provider-dept-8001做为服务提供者、启动consumer-dept-feign服务消费者:
能够看到服务提供者已经注册进去并正常运行:
经过客户端consumer-feign的81端口也能访问到对应的id数据:
(5)模拟服务熔断异常:
关闭服务提供方provider-dept-8001,同时访问81端口的数据请求:
能够看到此时调用到了咱们编写的fallbackFactory中的回调方法显示降级信息。
因此即便服务关闭以后,Hystrix的服务熔断机制也能避免大量重复无效访问带来的服务异常,能较好的提供客户体验。
本节涉及实例及相关代码已上传至github:
https://github.com/devyf/SpringCloud_Study/tree/main/springcloud_hello