前言
请在看这篇文章之前先看
https://blog.youkuaiyun.com/dtttyc/article/details/88863871
什么是Hystrix
她是一个库,通过添加容错和延迟逻辑等,让你控制分布式服务之间的交互
她通过隔离服务之间的访问点,阻止他们之间级联故障,提高整个系统的弹性
为什么使用Hystrix
1 访问消费者客户端访问由于网络原因导致的延迟或者是故障
2 复杂的分布式避免级联故障
3 快速失败,迅速恢复
4 优雅的降级
5 实时监控和警告
分布式系统面临什么问题
如果是正常情况下来说,这一条线得到结果是没有问题的,但是如果Dependency1故障,那么所有线程会阻塞到Dependency,会产生雪崩显现
正常情况
非正常情况
什么是雪崩?什么是扇出?
A依赖b,b依赖C. 如果传出扇出的链路上某个微服务响应时间非常长或者已经停止响应,那么这个时候对A服务的调用会占用越来越多的资源,然后进入系统崩溃, 这个就是雪崩效应
Hystrix如何工作
- 调用方返回一个符合预期的可处理的备选响应,fallBack
- 不是长时间的等待或者异常
- 减少长时间占用资源,避免系统崩溃,也就是雪崩
熔断使用
什么是服务熔断
一般是某个服务故障或者异常引起,当某个异常条件被触发,直接熔断整个服务, 而不是一直等待服务超时
1 引入pom文件
<dependency>
<groupId> org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
2 启动项加注解
@EnableCircuitBreaker //hystrix熔断
3 control加注解和备选方法
@RequestMapping(value = "/dept/get/{id}", method = RequestMethod.GET)
//重点看fallbackMethod 方法
@HystrixCommand(fallbackMethod = "processHystrix_Get")
public Dept get(@PathVariable("id") Long id)
{
Dept dept=service.get(id);
if (dept==null){
throw new RuntimeException("出错");
}
return dept;
}
//当发生异常的时候走这个方法,可以保证不会占用资源,导致系统雪崩
public Dept processHystrix_Get(@PathVariable("id") Long id)
{
return new Dept().setDeptno(id).setDb_source("未知").setDname("只有id信息,"+id);
}
4更改服务的名称以免混淆,在application.yml文件更改
spring:
application:
name: microservicecloudhystrix-dept8081
注解当我们更改了服务名称之后一定要把所有涉及到服务名称的地方全部修改,否则会报找不到服务名词的错误
服务降级
一般是从整体负荷考虑,都某个服务资源不够的时候让另一个服务关闭,客户端可以给自己准备一个本地fallback回调,当调用的时候返回一个缺省值
上面熔断的方式确实不错,我们每个方法都有备选的方案,但是如果我们有10000个方法, 那么需要对着10000个方法都有备选方法吗? 也就是熔断的方法和我们的control方法太耦合了,所以下面使用接口的方式来解耦合
在API层添加注解
//@FeignClient(value = "microservicecloudhystrix-dept8081")
@FeignClient(value = "microservicecloud-dept8081",fallbackFactory = DeptClientServiceFallbackFactory.class)
创建实现FallbackFactory接口的类
//@Company一定要加,否则报错,也就是工厂没有注入到spring容器里面
@Component
public class DeptClientServiceFallbackFactory implements FallbackFactory<DeptClientService>{
@Override
public DeptClientService create(Throwable throwable) {
return new DeptClientService() {
@Override
public Dept get(long id) {
return new Dept().setDeptno(id).setDb_source("未知").setDname("只有id信息,"+id);
}
@Override
public List<Dept> list() {
return null;
}
@Override
public boolean add(Dept dept) {
return false;
}
};
}
}
当不加@component会出现的错误
当我把提供者的服务提供者的服务关闭之后,也就是降级之后出现提示信息,这样可以保证不会出现雪崩的情况
总结
嘻嘻