Spring-Cloud 服务容错保护 Hystrix
1. 灾难性的雪崩效应
在微服务架构中,一个请求需要调用多个服务是非常常见的。如客户端访问A服务,而A服务需要调用B服务,B服务需要调用C服务,由于网络原因或者自身的原因,如果B服务或者C服务不能及时响应,A服务将处于阻塞状态,直到B服务C服务响应。此时若有大量的请求涌入,容器的线程资源会被消耗完毕,导致服务瘫痪。服务与服务之间的依赖性,故障会传播,造成连锁反应,会对整个微服务系统造成灾难性的严重后果,这就是服务故障的“雪崩”效应。如下图所示:
2.解决灾难性雪崩效应的方法
2.1 降级
超时降级、资源不足时(线程或信号量)降级,降级后可以配合降级接口返回托底数据。实现一个 fallback 方法, 当请求后端服务出现异常的时候, 可以使用 fallback 方法返回的值.
2.1.1 实例:
2.1.1.1 创建项目
2.1.1.2 添加pom坐标
2.1.1.3 创建全局性配置文件
2.1.1.4 创建启动类
2.1.1.5 编写product实体类
2.1.1.6 编写配置类
2.1.1.6 编写service接
2.1.1.7 编写controller
2.1.1.8 测试
当provider不能服务时返回托底数据
2. 2 缓存
Hystrix 为了降低访问服务的频率,支持将一个请求与返回结果做缓存处理。如果再次请求的 URL 没有变化,那么 Hystrix 不会请求服务,而是直接从缓存中将结果返回。这样可以大大降低访问服务的压力。
Hystrix 自带缓存。有两个缺点:
1. 是一个本地缓存。在集群情况下缓存是不能同步的。
2. 不支持第三方缓存容器。Redis,memcache 不支持的。可以使用 spring 的 cache。spring的cache对redis是支持的
2.2.1 使用缓存解决雪崩效应(拷贝降级项目)
2.2.1.1 添加坐标
2.2.1.2 修改全局配置文件
2.2.1.3 修改摄入service 接口
2.2.1.4 修改controller接口
2.2.1.5 修改启动类
2.2.1.6 测试
2.3 请求合并
在微服务架构中,我们将一个项目拆分成很多个独立的模块,这些独立的模块通过远程调用来互相配合工作,但是,在高并发情况下,通信次数的增加会导致总的通信时间增加,同时,线程池的资源也是有限的,高并发环境会导致有大量的线程处于等待状态,进而导致响应延迟,为了解决这些问题,我们需要来了解 Hystrix 的请求合并。
没合并的请求
请求合并
2.3.1 使用请求合并解决服务性雪崩(拷贝降级项目)
2.3.1.1 修改全局配置文件
2.3.1.2 修改service接口
2.3.1.3 修改controller
2.3.1.4 观察控制台的结果
原理解析:请求合并将大量的请求合并一个,将这些合并的请求参数封装在数组内,一同向provider请求,返回结果再分发给各个客户端浏览器。
2.3.1.5 什么情况下使用请求合并
在微服务架构中,我们将一个项目拆分成很多个独立的模块,这些独立的模块通过远程
调用来互相配合工作,但是,在高并发情况下,通信次数的增加会导致总的通信时间增加,
同时,线程池的资源也是有限的,高并发环境会导致有大量的线程处于等待状态,进而导致
响应延迟,为了解决这些问题,我们需要来了解 Hystrix 的请求合并。
2.3.1.6 请求合并的缺点
设置请求合并之后,本来一个请求可能 5ms 就搞定了,但是现在必须再等 10ms 看看还
有没有其他的请求一起的,这样一个请求的耗时就从 5ms 增加到 15ms 了,不过,如果我们
要发起的命令本身就是一个高延迟的命令,那么这个时候就可以使用请求合并了,因为这个
时候时间窗的时间消耗就显得微不足道了,另外高并发也是请求合并的一个非常重要的场
景。
2.4 熔断
当失败率(如因网络故障/超时造成的失败率高)达到阀值自动触发降级,熔断器触发的快速失败会进行快速恢复。
2.4.1 使用熔断解决服务性雪崩效应(拷贝降级的项目)
2.4.1.1 修改全局配置文件:
2.4.1.2 修改service接口
2.4.1.3 修改controller
2.4.1.4 其他不变,启动测试
2.4.2 熔断参数参考
2.5 隔离(线程池隔离和信号量隔离)
限制调用分布式服务的资源使用,某一个调用的服务出现问题不会影响其他服务调用。
线程池隔离:
2.5.1 线程池隔离(拷贝降级)
2.5.1.1 修改全局配置文件
2.5.1.2 修改service接口
2.5.1.3 修改controller
2.5.1.4 线程池隔离相关参数
2.5.2 信号量隔离
2.5.2.1 信号量隔离的相关参数
2.5.2.2 使用信号量隔离解决服务雪崩效应(拷贝线程隔离项目)
2.5.2.2.1 修改全局配置文件
2.5.2.2.2 修改service接口
2.5.2.2.3 其他一致,启动测试
2.5.3 线程池隔离和信号量隔离 的 区别
3.Feign 的雪崩处理
3.1 Feign 的服务降级处理
3.1.1 创建项目(拷贝上篇feign的使用)
3.1.2 修改全局配置文件
3.1.3 修改service接口
3.1.4 修改controller
3.1.5 创建ProductServiceFallback类
3.1.6 启动测试
3.2 Feign 降级后的异常记 录(拷贝feign的降级项目)
3.2.1 修改ProductServiceFallbackFactory类
3.2.2 修改service接口
3.2.3 启动测试
3.3 Feign配置全局性熔断(拷贝降级日志记录项目)
3.1.3 在全局性配置文件添加配置
4. hystrix工作原理(重点)
1:每次调用创建一个新的HystrixCommand,把依赖调用封装在run()方法中.
2:执行execute()/queue做同步或异步调用.
3:判断熔断器(circuit-breaker)是否打开,如果打开跳到步骤8,进行降级策略,如果关闭进入步骤4.
4:判断线程池/队列/信号量是否跑满,如果跑满进入降级步骤8,否则继续后续步骤.
5:调用HystrixCommand的run方法.运行依赖逻辑
5a:依赖逻辑调用超时,进入步骤8.
6:判断逻辑是否调用成功
6a:返回成功调用结果
6b:调用出错,进入步骤8.
7:计算熔断器状态,所有的运行状态(成功、失败、拒绝、超时)上报给熔断器,用于统计从而判断熔断器状态.
8:getFallback()降级逻辑.
以下四种情况将触发getFallback调用:
(1):run()方法抛出非HystrixBadRequestException异常。
(2):run()方法调用超时
(3):熔断器开启拦截调用
(4):线程池/队列/信号量是否跑满
8a:没有实现getFallback的Command将直接抛出异常
8b:fallback降级逻辑调用成功直接返回
8c:降级逻辑调用失败抛出异常
9:返回执行成功结果