前言:
在复杂分布式架构体系中,应用程序往往会有数十个依赖关系,而每个依赖关系在某些时候将不可避免的失败,造成当前服务不可用,而在高并发的环境下,当服务挂掉后,服务消费者依然在请求服务,这就会走造成当前服务的瘫痪,即便被重试唤醒,但面临堆积起来的大量服务请求,服务提供者会再次挂掉,这就是服务雪崩
服务雪崩
通俗的说:当服务间的关系非常复杂,耦合高,那么当一个服务挂掉了,那么跟他存在依赖关系的服务也就相应的会被阻塞,这就是雪崩效应,
解决:服务熔断,服务降级
服务熔断和降级区别
例子:
总结:服务熔断:就是当一个微服务的某个程序模块出现了问题,导致当前服务挂掉,触发熔断机制,给这个程序模块一个(备选方案),用来顶替坏掉的方法,让当前服务可以正常运行
触发原因:服务的某个模块(如:方法)异常/挂掉/超时
解决:启用备份方法顶替原有方法
目的:让服务正常运行,一般是给用户可视化的相关错误信息而不是一堆异常信息,提高系统的容错性的同时增强用户的体验性
服务降级:某给服务并发量过高,cpu承受不了,关闭部分不重要服务,节省资源占用
触发原因:开发人员主动关闭某服务
解决方案:执行备选服务,给客户端提醒信息,当前服务不可用
目的:节省cpu资源,交给并发量高的服务去使用
注意:服务熔断是在服务端(服务提供者),服务降级是客户端开发(服务消费者),两者开发位置不同
服务熔断是被动的,降级是主动的
Hystrix是什么
是一个对微服务架构中的异常进行处理一个中间件,如服务雪崩;提高了分布是系统的容错性,不会因为某些服务模块的挂掉而影响整个系统的正常运行
Hystrix作用
- 基于命令模式的请求:解耦了请求者和接受者,使得发送出去的命令可以排队、异步执行。
- 资源隔离:用ConcurrentHashMap绑定commandKey和线程池,当某个功能运行不稳定或有问题时,服务的其他部分不受影响。服务恢复比较快。
- 熔断和服务降级:用ConcurrentHashMap绑定commandKey和HystrixCircuitBreaker类(断路器类),统计每次请求的结果并记录,根据结果判断是否开启断路器,自定义异常返回结果实现熔断降级。
一,服务熔断配置
@EnableCircuitBreaker 开启断路器,属于hystrix的包
1.导入依赖
<!--Hystrix--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix</artifactId> <version>1.4.6.RELEASE</version> </dependency>
2.服务提供者controller层方法处加服务熔断相关注解,本质给方法加备选方案(当服务挂了,备选方案被调用)
@HystrixCommand(fallbackMethod = "备选方案方法名")
//提供Restful服务 @RestController public class DeptController { @Autowired private DeptService deptService; @GetMapping("/dept/get/{id}") @HystrixCommand(fallbackMethod = "hystrixGet") public Dept get(@PathVariable("id") Long id){ Dept dept = deptService.queryById(id); if(dept == null){ throw new RuntimeException("id=>"+id+"不存在该用户,或者信息无法找到~"); } return dept; } //熔断版的(本质,备选方法) public Dept hystrixGet(@PathVariable("id") Long id) { return new Dept() .setDeptno(id) .setDname("id=>"+id+"不存在该用户,或者信息无法找到~") .setDb_source("no this datasource in MySQL"); } }
3.主启动类开启断路器
@EnableCircuitBreaker //开启断路器,属于hystrix的包
@SpringBootApplication @EnableDiscoveryClient //服务发现,企业级协同开发 @EnableEurekaClient //开启eureka客户端,在服务启动后自动注册到指定的EurekaServer中 @EnableCircuitBreaker //开启断路器,属于hystrix的包 public class DeptProvider_8001 { public static void main(String[] args) { SpringApplication.run(DeptProvider_8001.class,args); } }
二,服务降级配置(feign的包集成了hystrix)
在api+服务消费者端配置
1.api端(共有端)配置,
作用:服务各服务的一个端,通常引封装成pom方式各端使用
(1)服务降级后触发的类
//服务降级 @Component public class DeptClientServiceFallBackFactory implements FallbackFactory { @Override public DeptClientService create(Throwable throwable) { return new DeptClientService() { @Override public Dept queryById(Long id) { return new Dept() .setDeptno(id) .setDname("id=>"+id+"没有对应的信息,客户端提供了降级的信息,这个服务已经被关闭") .setDb_source("没有数据~"); } @Override public List<Dept> queryAll() { return null; } @Override public Boolean addDept(String dname) { return null; } }; } }
(2)绑定服务降级的类
//注册到spring容器里 @Component //绑定服务id,fallback服务降级(绑定的类) @FeignClient(value = "SPRINGCLOUD-PROVIDER-DEPT",fallbackFactory = DeptClientServiceFallBackFactory.class) public interface DeptClientService { @GetMapping("/dept/get/{id}") Dept queryById(@PathVariable("id") Long id); @GetMapping("/dept/list") List<Dept> queryAll(); @PostMapping("/dept/add") Boolean addDept(String dname); }
2.服务消费者端配置‘(yaml)
#开启降级,feign,Hystrix共用,默认false
feign:
hystrix:
enabled: true