1. 雪崩效应
1.1 定义
在微服务架构中,出现一种链式的调用关系,比如:A调用B,B调用C,B调用C。当请求量较少时,上述的调用是不会出现问题的
但是,当某一个服务(A)突然遇到大量请求时,整个链条所有服务负载剧增。此时,除了A,B服务之外,还有其他要调用C服务的服务出现问题,从而导致所有的项目出现问题。这种情况就叫做灾难性的雪崩效应
1.2 原因
- 服务提供者不可用,如:硬件故障,程序BUG,缓存击穿,并发请求量过大等
- 重试流量加大,如:用户重试,代码重试逻辑等
- 服务调用者不可用,如:同步请求阻塞造成的资源耗尽等
1.3 结果
雪崩效应最终的结果:服务链条种的某一个服务不可用,导致一系列的服务不可用,最终造成服务逻辑崩溃
2. 如何防治雪崩效应
2.1 降级
当资源不足时,用户发出的请求没有办法在一定的时间内得到回应。此时不应该再让其继续等待下去,而是对此次的请求进行降级处理
服务降级后,通过编写回调接口,实现回调方法,给前端返回托底数据(比如:弹窗提示等),让此次的请求结果以另一种结果和方式返回给前端
当请求后端微服务出现异常时,也可以使用 fallback 方法的返回值
其实下面提到的所有 fallbackMethod(回调方法) 都是降级
2.2 熔断
当失败率(如10次请求,5次失败)达到阀值,自动触发降级
熔断器触发的快速失败会进行快速恢复
由于某些原因使得服务出现了过载现象,为防止造成整个系统故障,从而采用的一种防护措施,也成为过载保护
2.2.1 特点
- 熔断就是具有特定条件的降级
- 保证服务出现问题后,整个项目还可以继续运行
- 牺牲局部服务,保全整体系统稳定性的措施
2.2.2 降级和熔断的区别
- 降级是每次都会去访问对应的服务,如果出现了超时或资源不足就执行回调方法,返回托底数据
- 熔断是当达到失败率后,不会再次去访问以下的服务,直接返回托底数据
2.3 请求缓存
将数据存储在缓存里,每次访问先走缓存,缓存没有再去访问对应的服务获取数据
2.4 请求合并
当A服务调用B服务时,如果请求突然剧增,那么可以设置在一定时间内(比如每 5ms)将所有请求合并在一起,减少对B服务的负载
缺点:如果一个请求本来 5ms 就搞定了,但是现在必须等 10ms 看看有没有其他的请求一起,这样这一个请求就从原来的 5ms 变成了 15ms
所以在使用时,要先确定,是否是一个高延迟的命令,如果是的话,就可以用请求合并了,因为这个时候等待所花的时间与延迟的时间对比起来,显得微不足道
2.5 隔离
分为:线程池隔离和信号量隔离
通过判断线程池或信号量是否已满,超出容量的请求直接降级,从而达到限流的效果
2.5.1 线程池隔离
没有线程池隔离的项目,所有接口都运行在一个线程池中,当某一个接口访问的压力变大或出现故障时,会导致资源耗尽从而影响到其他的接口的调用而引发雪崩效应
2.5.1.1 隔离前
2.5.1.2 隔离后
2.5.1.3 优点
- 可以安全隔离依赖的服务,减少所依赖服务发生故障时的影响面
- 当失败的服务再次变得可用时,线程池将清理并立即恢复,而不需要一个长时间的恢复
- 独立的线程池也提高了并发性
2.5.1.4 缺点
- 请求在线程池中执行,肯定会带来任务调度,排队和上下文切换带来的CPU开销
- 因为涉及到跨线程,那么就存在 ThreadLocal 数据的传递问题,比如在主线程初始化的ThreadLocal变量,在线程池中无法获取
2.5.2 信号量隔离
每次调用线程,当前请求通过计数信号量进行限制,当信号量大于最大请求数时进行限制,调用 fallback 接口快速返回
但是信号量的调用是同步的,也就是说,每次调用都得阻塞调用方的线程,直到结果返回。这样就导致了无法对访问做超时处理,只能依靠调用协议超时,无法主动释放
2.5.3 总结
线程池隔离:
- 请求线程和调用线程不是同一条线程
- 支持超时,可直接返回
- 支持熔断,当线程池到达 maxConcurrentRequests(最大请求数) 后,再请求会触发 fallback(回调) 接口进行熔断
- 隔离原理:每个服务单独使用线程池
- 支持同步和异步两种方式
- 资源消耗大,大量的线程上下文切换、排队、调度等,容器造成及其负载高
- 无法传递 Http Header
- 请求并发大,耗时长(计算大,或操作关系型数据库)采用线程池隔离
信号量隔离:
- 请求线程和调用线程是同一条线程
- 不支持超时,但支持熔断,当信号量到达 maxConcurrentRequests(最大请求数) 后,再请求会触发 fallback(回调) 接口进行熔断
- 隔离原理:通过信号量的计数器
- 同步调用,不支持异步
- 资源消耗小,只是一个计数器
- 可以传递 Http Header
- 请求并发大,耗时短(计算小,或操作缓存),采用信号量隔离
3. 相关解决技术
熔断器-Hystrix:https://github.com/Netflix/Hystrix
服务哨兵-Sentinel:https://sentinelguard.io/zh-cn/