Spring Cloud Alibaba 雪崩效应和容错解决方案
文章目录
- 1. 雪崩效应
- 1.1. 举个例子:
- 2. 常见的容错方案:
- 2.1.超时:
- 2.2. 限流:
- 2.3. 仓壁模式:
- 2.3.1. 现实中的仓壁模式:
- 2.3.2. 软件中的仓壁模式:
- 2.4. 断路器模式
- 2.4.1. 现实中的断路器:
- 2.4.2. 软件中的断路器:
1. 雪崩效应
微服务架构的系统包含很多微服务,微服务之间通过轻量级的通信机制进行通信,构建成了一个完成的应用系统。但是,每个微服务不能保证100%可用的,网络呢?有时也会出问题
1.1. 举个例子:
现在有一个高并发的应用系统它包含4个微服务,一开始每个微服务都是正常的,然后,在某一个时间点,微服务A突然挂了,所有的实例都挂了,而这是一个高并发的应用系统.
B服务还在分光的调用A服务的API呢,现在A服务挂了,现在B服务发往A服务的请求,就会强制等待 ,直到请求超时,而在java程序里面,一个请求呢,往往对应着一个线程,如果请求被强制等待,那么线程就会被强制阻塞,一直到请求超时的时候,这个线程才会被释放,由于,这是一个高并发的应用系统,阻塞的线程就会越来越多,而线程对应的服务器的计算资源,比方说内存、cpu,如果不作任何处理的话,终有一天B服务所在的服务器,再也无法创建新的线程了,于是B服务也挂了。
简言之,B服务是被A服务拖垮的,同样的道理,C服务和D服务调用B服务,C和D 也会被B服务拖垮,我们把基础服务故障导致上层服务故障,并且这个故障不断放大的过程,称之为雪崩效应,这样现象就像是滚雪球一样越滚越大,最后整个服务可能都挂了,在一些英文书里面常常把雪崩效应称之为cascading failure 级联失效 级联故障。
2. 常见的容错方案:
A服务挂了,B服务做好了容错,就不会被A服务拖垮。
业界常使用的使用这些容错方案,可以有效的避免雪崩效应
2.1.超时:
比如说为每一次请求设置超时时间,假若为1s,不管这次请求会不会成功,这个线程就会被释放,这样只要线程释放的速度够快,那么,B服务就不会被A服务拖垮了
2.2. 限流:
在一个高并发的应用系统中,采坑能存在大量的线程阻塞,如果我们经过评估,发现微服务B的实例最大能够承载的qps是1000,那么,我们就可以为微服务B设置一个限流的值,比方说是800qps,或者其他一个低于1000qps的阈值,这个时候,只要某一个实例达到这个阈值,再有流量进来,就直接拒绝,通过这种方式,也实现了对自己的保护,至少B服务不会被A服务拖到宕机。
2.3. 仓壁模式:
2.3.1. 现实中的仓壁模式:
泰坦尼克号,号称永不沉没的船,是基于技术而言的,用到了仓壁模式,一条船被划分了3个船舱,每个船舱之间,用2块钢板焊死,即使,某一个船舱进水也不会影响其他船舱,当时,泰坦尼克号的设计能够容纳2个主仓的进水船依然能够正常工作,所谓主仓就是中间两边两个比较大的仓。3个仓进水了,超出了泰坦尼克号的容错能力,于是,就悲剧了。
2.3.2. 软件中的仓壁模式:
AController 有自己独立的线程池,比方叫thread-pool-1 coreSize=10
调用其他API挂了,对于高并发的应用,这个线程池就满了,然后,去排队,再然后就直接拒绝了,线程池大家应该是很熟悉,线程池有自己的拒绝策略。
同理,BController 有自己独立的线程池,比方叫thread-pool-2 coreSize=10,
此时,AController 线程池满了或者拒绝了不会影响BController ,因为都有自己的线程池。
如果用船舱的例子类比的话,现在这2个Controller 就好比2个船舱,Controller 之间用2个独立的线程池焊死,AController 类中的API调不通,就相当于这个船仓进水了,那么,你的船舱进水和我的船舱没有关系,这就是仓壁模式。
2.4. 断路器模式
断路器是服务容错里面最高端的方案
2.4.1. 现实中的断路器:
每个人家里都有断路器,就是电闸。
断路器说白了就是监控加开关,它会实时监控电路的状态,但发现某段时间内,电流过大,他就认为电路短路了,然后就会跳闸,从而保护电路不被烧毁。
2.4.2. 软件中的断路器:
举个栗子:
比如说AController 中,调用API时,我监控5s以内的错误率、错误次数等等,如果错误率达到阈值又或者错误次数达到一定的阈值,我就认为调用的服务已经挂了,然后就跳闸,不去调用远程的api服务了。
正常状态下,断路器关闭