服务容错
为什么需要服务容错?
服务之间存在调用关系,如果被调用服务down掉,处理不及时的话,就会造成雪崩效应,又称级联故障、级联失效(cascading failure)
如图所示,C,D服务调用B服务,B服务调用A服务,如果A服务突然发生故障,那么B服务调用A服务就得不到返回,直到请求超时,在超时之前的那段时间内,请求一直在等待,简直欲穿秋水,一个请求就是一个线程,线程一直处于阻塞状态,会一直占用服务器的资源,比如内存,cpu;如果B的并发很高,这样阻塞的线程很多,那么B服务器再也没有资源去创建新的线程,于是B也挂了,然后C,D服务又请求不到B服务了…然后C,D服务也挂了。因为A服务的故障,BCD没有做任何处理,都挂了,这就是雪崩效应
服务容错的目的就是保护自己服务的正常运行。比如B服务碰到上面那种请求等待导致线程太多的时候,就限流,请求的线程数不得超过10个,超过10个就不再接受新的请求,直接返回被限流错误提示,这样B服务就不会因为太多线程耗尽内存。
常见的容错方案
- 超时 设置请求超时时间,让请求线程在等待超过一定的时间后就判定为请求失败从而释放请求线程,在某些场景下线程释放得够快的话,就不会因为不断创建线程而导致资源耗尽引起的服务崩溃。
- 限流 我们经过测试,发现某个请求能够承受的最大QPS(每秒查询率)是1000,那我们就把这个请求的QPS阈值设置成800,超过了这个阈值,请求直接返回被限流的错误。
- 仓壁模式(设置独立线程池,空间相对隔离)
舱壁模式实际上就是借鉴于现实生活中的船舱结构而设计,一艘船想要不那么容易沉也需要具备有一定的”容错“能力,而早期的船由于设计上的欠缺,只要一个地方进水了,那么水就会逐渐漫进整个船舱,这种结构的船几乎没有“容错”能力,所以就比较容易沉。于是此时就有人想到将原本一体的船舱分隔成一个个独立的船舱,船舱之间都使用钢板焊死隔开,这些钢板就是所谓的舱壁了。采用这种设计后,就算当其中一个两个船舱进水了,也不会影响到其他船舱,这艘船依旧能够正常行驶。
在软件层面上借鉴这种思想,我们可以让每个服务都运行在自己独立的线程池中,线程池之间是互不干扰的,服务A的线程池资源耗尽也不会影响到服务B。此时线程池就像船舱的舱壁一样将不同的服务资源隔离开来,这样某个服务挂掉也不会影响其他服务的运行。
- 断路器模式
检测一定时间内的错误率,错误数,比如5秒之内错误率,错误次数,达到某个阈值,就认为B服务所调用的A服务挂了,就跳闸(打开断路器),就不会堆积那么多线程等待了,然后在10秒之后(称作断路器时间窗口),断路器就变成半开状态,此状态向A再次发送仅一次请求,如果这次请求又失败了,就再跳闸(断路器打开状态),默认等待10秒(断路器时间窗口,不是非得10秒,这个值可以自定义),断路器又变成半开状态,再次向A发送一次请求,如果这次请求成功了,断路器就彻底恢复,闸彻底闭合
Sentinel是什么
Sentinel的官方标题是:分布式系统的流量卫兵。从名字上看,很容易猜到它是用来做服务稳定性保障的。对于服务稳定性保障组件,如果熟悉Spring Cloud的用户,第一反应肯定是Hystrix。但是比较可惜的是 Netflex 已经宣布对 Hystrix 停止更新。那么,在未来我们还要什么更好的选择呢?除了Spring Cloud 官方推荐的 resilience4j之外,目前Spring Cloud Alibaba下整合的 Sentinel也是用户重点考察和选型的目标。
Sentinel的功能和细节比较多,一篇内容很难介绍完整。这篇文章只是让我们对Sentinel有一个整体的认识,后面我们会对如何把 Sentinel 整合到Spring Cloud 应用中做详细的介绍。
随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。
Sentinel 具有以下特征
- 丰富的应用场景: Sentinel 承接了阿里巴巴近10年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰天谷、集群流量控制、实时熔断下游不可用应用等。
- 完备的实时监控:Sentinel 同时提供实时的监控功能。你可以在控制台中看到接入应用的单台机器秒级数据,甚至500台以下规模的集群汇总运行情况。
- 广泛的开源生态:Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与Spring Cloud 、Dubbo、 gRPC的整合。只需要引入相应的依赖并进行简单的配置即可快速的接入Sentinel。
- 完整的 SPI 扩展点: Sentinel 提供简单易用、完善的 SPI 扩展接口。你可以通过实现扩展接口来快速的定制逻辑。例如定制规则管理、适配动态数据源等。
Sentinel的主要特征:
Sentinel 的开源生态: