服务熔断降级

本文介绍了在服务出现故障时的解决方案,包括资源隔离、服务熔断和降级。资源隔离采用线程池和信号量策略。服务熔断是为了临时关闭某些功能,保证系统整体可用,而服务降级则是有损服务,确保系统柔性可用。文章详细阐述了断路器的状态流转和统计阈值,并提及Hystrix作为服务隔离组件的作用和主要特性。
摘要由CSDN通过智能技术生成

之前给大家讲了很多服务之前的关系,今天主要给大家介绍,当服务出现问题时,我们该如何解决。

首先我们先进行一些场景分析:

  • 场景一

在这里插入图片描述

服务提供端提供了A、B、C、D 4个服务,服务调用方调用服务时,D服务出现了问题,导致调用服务D的请求都出现了超时或者错误,从而进一步影响了整个请求队列的性能。

  • 场景二

在这里插入图片描述

我们根据client1和client2 的请求压力确定了我们serverA的负载情况,但是当client2的请求从1500 增加到15000 时,会远远大于ServerA 的性能瓶颈,这个时候也会导致Client1的请求出现超时或者失败的情况。

总结一下,会有哪些情形导致我们服务出现不可以,需要我们做容错呢?

  • 单个节点故障,可能被无限向上放大
  • 多租户相互影响
  • 瞬时流量激增,系统扛不住

针对上面总结的场景,我们有哪些解决方案呢?

  • 资源隔离
  • 熔断
  • 降级

1、资源隔离

资源隔离主要是对线程资源进行隔离。这里有两种方法进行隔离:使用线程池和信号量

(1)线程池隔离

使用线程池进行资源隔离,我们有两种途径,一种是在服务端,根据不同的请求类型划分不同的队列进行处理,比如我们可以根据业务的优先级,创建高中低、默认等优先级队列来处理业务请求。

在这里插入图片描述

还有一种方式是通过在服务调用端进行队列划分,比如我们有多个服务进行调研,每个调用内部都有一个队列,通过连接管理的方式进行服务调用

在这里插入图片描述

(2)信号量

还有一种方式是通过信号量的方式来实现。我们可以通过给每个服务提供方设置可用的信号量来实现资源隔离。

在这里插入图片描述

(3)对比

信号量与线程池对比

对比项 线程切换 异步 超时 熔断 限流 开销
信号量
线程池

下面我们来具体分析下服务熔断和降级的设计应用。

2、服务熔断

什么叫服务熔断?

服务熔断就是临时关闭对某些功能的调用,个别的业务不可用,但是系统整体可用

有哪些服务熔断的具体例子呢?

比如一些大的电商平台在双11那天关闭退款入口,关闭换头像功能等等,这些功能的关闭对于用户来说是可感知的。

在做服务熔断设计中,我们需要关注哪些点呢?

  • 可熔断服务

我们需要判断在我们的整体架构中,哪些服务是可用进行熔断的,哪些是核心业务,不能出现不可用的情况。

  • 熔断触发:触发熔断的方式有哪些
    • 主动熔断:系统管理员根据将要出现的场景,提前关闭某些服务
    • 被动熔断:系统根据服务的状态触发熔断
  • 恢复时机

3、服务降级

什么叫服务降级?

服务降级就是有损的提供服务,保证服务柔性可用。

业务中有哪些服务降级的场景呢?

比如我们在请求高峰期的时候,对于用户的个人推荐,我们返回兜底数据;计数服务返回假数据等。这些服务对于用户来说他是不易感知的。

我们在进行服务降级设计时,需要考虑到哪些方面呢?

  • 可降级服务

首先我们要确认在我们的整体架构中,哪些服务是可以采用降级的方案的,哪些场景不适合降级的方法

  • 降级方法

我们一般的降级方法有哪些,比如常见的默认返回等等

  • 降级触发

降级触发的条件是什么,现在有2种常见的情况:主动和被动

主动:管理员发现某个服务出现异常,通过手动的方式触发某个服务的熔断,这是我们需要有一个降级的方法

被动:当某个服务调用超时或者异常,采用降级方案

  • 恢复时机

触发降级服务后,什么时候恢复到原来的服务?

4、熔断降级

基于上面的描述,我们可以发现,降级熔断都是系统可用性可靠性的保障手段,为了保障服务的柔性可用。

  • 目标一致:都是从可用性和可靠性出现,为了防止系统崩溃
  • 用户体验:用户感受到某些功能的暂不可用

很多时候,降级和熔断是配置使用的

5、断路器设计

断路器

服务熔断的开关,当对下游服务调用异常量达到设定阈值后,打开断路器,触发熔断

(1)断路器的状态流转

在这里插入图片描述

  • 断路器的状态分为3个状态,closed(关闭),open(打开),half open(半打开),服务正常使用时,断路器的状态为关闭的;
  • 当服务调用在指定时间内达到一定的阈值,就会打开断路器,服务熔断;
  • 当达到关闭时间后,会将断路器的状态更新为halfopen,将少部分流量打到之前熔断的服务;
  • 如何服务调用正常,则将断路器状态更新为closed,否则更新为open
(2)阈值与统计数据
  • 阈值的数据类型
    • 我们一般采用百分比的方式,比如失败率达到多少多少我们出发熔断
  • 颗粒度
    • 我们一般是针对某个节点中的某个实例的某个方法而言,当某个方法的调用失败率达到一定的程度,我们就触发对该方法调用的熔断
  • 统计

在这里插入图片描述

数据结构:如上图,我们需要在规定的时间范围内进行统计,只需要统计最近10个slot范围内的数据,根据场景,我们的数据结构可以是链表,或者循环数组,滑动窗口伪代码实现如下:

// 整个循环数组的结构
public class BucketCircularArray {
   
  private volatile int size =10;
  private static int maxSize = 60;
  private volatile int dataLength;
  private Bucket[] data; 
  private int head;
  private int tail;
}

// 每个slot的数据结构
public class Bucket {
   
  private final long windowStart;
  private AtomicInteger successNum;
  private AtomicInteger failNum;
  private AtomicInteger timeoutNum;
}
public void addBucket(Bucket bucket) {
   
  data[tail] = bucket;
  incrementTail();
}

private void incrementTail() {
   
  if (dataLength == size) {
   
    // the size change
    head = (head + 1) % size;
    tail = (tail + 1) % size;
  } else 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值