首页 > 其他分享 >限流、熔断、服务降级

限流、熔断、服务降级

时间:2023-12-18 18:46:59浏览次数:33  
标签:降级 服务 请求 断路器 熔断 限流

 

在分布式系统中,如果某个服务节点发生故障或者网络发生异常,都有可能导致调用方被阻塞等待,如果超时时间设置很长,调用方资源很可能被耗尽。这又导致了调用方的上游系统发生资源耗尽的情况,最终导致系统雪崩。

 

如果 D 服务发生了故障不能响应,B 服务调用 D 时只能阻塞等待。假如 B 服务调用 D 服务设置超时时间是 10 秒,请求速率是每秒 100 个,那10秒内就会有 1000 个请求线程被阻塞等待,如果B的线程池大小设置 1000,那 B 系统因为线程资源耗尽已经不能对外提供服务了。而这又影响了入口系统 A 的服务,最终导致系统全面崩溃。

提高系统的整体容错能力是防止系统雪崩的有效手段。

在 Martin Fowler和James Lewis 的文章 《Microservices: a definition of this new architectural term》[1]中,提出了微服务的 9 个特征,其中一个是容错设计。

要防止系统发生雪崩,就必须要有容错设计。如果遇到突增流量,一般的做法是对非核心业务功能采用熔断和服务降级的措施来保护核心业务功能正常服务,而对于核心功能服务,则需要采用限流的措施。

限流

当系统的处理能力不能应对外部请求的突增流量时,为了不让系统奔溃,必须采取限流的措施。

1.1 限流指标

1.1.1 TPS

系统吞吐量是衡量系统性能的关键指标,按照事务的完成数量来限流是最合理的。

但是对实操性来说,按照事务来限流并不现实。在分布式系统中完成一笔事务需要多个系统的配合。比如我们在电商系统购物,需要订单、库存、账户、支付等多个服务配合完成,有的服务需要异步返回,这样完成一笔事务花费的时间可能会很长。如果按照TPS来进行限流,时间粒度可能会很大大,很难准确评估系统的响应性能。

1.1.2 HPS

每秒请求数,指每秒钟服务端收到客户端的请求数量。

如果一个请求完成一笔事务,那TPS和HPS是等同的。但在分布式场景下,完成一笔事务可能需要多次请求,所以TPS和HPS指标不能等同看待。

1.1.3 QPS

服务端每秒能够响应的客户端查询请求数量。

如果后台只有一台服务器,那 HPS 和 QPS 是等同的。但是在分布式场景下,每个请求需要多个服务器配合完成响应。

目前主流的限流方法多采用 HPS 作为限流指标。

1.2 限流方法

1.2.1 流量计数器

这是最简单直接的方法,比如限制每秒请求数量 100,超过 100 的请求就拒绝掉。

但是这个方法存在 2 个明显的问题:

  • 单位时间(比如 1s)很难把控,如下图

 

这张图上,从下面时间看,HPS 没有超过 100,但是从上面看 HPS 超过 100了。

有一段时间流量超了,也不一定真的需要限流,如下图,系统 HPS 限制 50,虽然前 3s 流量超了,但是如果读超时时间设置为 5s,并不需要限流。

 

1.2.2 滑动时间窗口

滑动时间窗口算法是目前比较流行的限流算法,主要思想是把时间看做是一个向前滚动的窗口,如下图:

 

开始的时候,我们把 t1~t5 看做一个时间窗口,每个窗口 1s,如果我们定的限流目标是每秒 50 个请求,那 t1~t5 这个窗口的请求总和不能超过 250 个。

这个窗口是滑动的,下一秒的窗口成了 t2~t6,这时把 t1 时间片的统计抛弃,加入 t6 时间片进行统计。这段时间内的请求数量也不能超过 250 个。

滑动时间窗口的优点是解决了流量计数器算法的缺陷,但是也有 2 个问题:

  • 流量超过就必须抛弃或者走降级逻辑

  • 对流量控制不够精细,不能限制集中在短时间内的流量,也不能削峰填谷

1.2.3 漏桶算法

漏桶算法的思想如下图:

 

在客户端的请求发送到服务器之前,先用漏桶缓存起来,这个漏桶可以是一个长度固定的队列,这个队列中的请求均匀的发送到服务端。

如果客户端的请求速率太快,漏桶的队列满了,就会被拒绝掉,或者走降级处理逻辑。这样服务端就不会受到突发流量的冲击。

漏桶算法的优点是实现简单,可以使用消息队列来削峰填谷。

但是也有 3 个问题需要考虑:

  • 漏桶的大小,如果太大,可能给服务端带来较大处理压力,太小可能会有大量请求被丢弃。

  • 漏桶给服务端的请求发送速率。

  • 使用缓存请求的方式,会使请求响应时间变长。

漏桶大小和发送速率这 2 个值在项目上线初期都会根据测试结果选择一个值,但是随着架构的改进和集群的伸缩,这 2 个值也会随之发生改变。

1.2.4 令牌桶算法

令牌桶算法就跟病人去医院看病一样,找医生之前需要先挂号,而医院每天放的号是有限的。当天的号用完了,第二天又会放一批号。

算法的基本思想就是周期性的执行下面的流程:

客户端在发送请求时,都需要先从令牌桶中获取令牌,如果取到了,就可以把请求发送给服务端,取不到令牌,就只能被拒绝或者走服务降级的逻辑。如下图:

 

 令牌桶算法解决了漏桶算法的问题,而且实现并不复杂,使用信号量就可以实现。在实际限流场景中使用最多,比如 google 的 guava 中就实现了令牌桶算法限流,感兴趣可以研究一下。

 

熔断

相信大家对断路器并不陌生,它就相当于一个开关,打开后可以阻止流量通过。比如保险丝,当电流过大时,就会熔断,从而避免元器件损坏。

服务熔断是指调用方访问服务时通过断路器做代理进行访问,断路器会持续观察服务返回的成功、失败的状态,当失败超过设置的阈值时断路器打开,请求就不能真正地访问到服务了。

 

2.1 断路器的状态

断路器有 3 种状态:

  • CLOSED:默认状态。断路器观察到请求失败比例没有达到阈值,断路器认为被代理服务状态良好。

  • OPEN:断路器观察到请求失败比例已经达到阈值,断路器认为被代理服务故障,打开开关,请求不再到达被代理的服务,而是快速失败。

  • HALF OPEN:断路器打开后,为了能自动恢复对被代理服务的访问,会切换到半开放状态,去尝试请求被代理服务以查看服务是否已经故障恢复。如果成功,会转成 CLOSED 状态,否则转到 OPEN 状态。

断路器的状态切换图如下:

2.2 需要考虑的问题

使用断路器需要考虑一些问题:

  • 针对不同的异常,定义不同的熔断后处理逻辑。

  • 设置熔断的时长,超过这个时长后切换到 HALF OPEN 进行重试。

  • 记录请求失败日志,供监控使用。

  • 主动重试,比如对于 connection timeout 造成的熔断,可以用异步线程进行网络检测,比如 telenet,检测到网络畅通时切换到 HALF OPEN 进行重试。

  • 补偿接口,断路器可以提供补偿接口让运维人员手工关闭。

  • 重试时,可以使用之前失败的请求进行重试,但一定要注意业务上是否允许这样做。

2.3 使用场景

  • 服务故障或者升级时,让客户端快速失败

  • 失败处理逻辑容易定义

  • 响应耗时较长,客户端设置的 read timeout 会比较长,防止客户端大量重试请求导致的连接、线程资源不能释放

 

服务降级

前面讲了限流和熔断,相比来说,服务降级是站在系统全局的视角来考虑的。

在服务发生熔断后,一般会让请求走事先配置的处理方法,这个处理方法就是一个降级逻辑。

服务降级是对非核心、非关键的服务进行降级。

3.1 使用场景

  • 服务处理异常,把异常信息直接反馈给客户端,不再走其他逻辑

  • 服务处理异常,把请求缓存下来,给客户端返回一个中间态,事后再重试缓存的请求

  • 监控系统检测到突增流量,为了避免非核心业务功能耗费系统资源,关闭这些非核心功能

  • 数据库请求压力大,可以考虑返回缓存中的数据

  • 对于耗时的写操作,可以改为异步写

  • 暂时关闭跑批任务,以节省系统资源

总结

限流、熔断和服务降级是系统容错的重要设计模式,从一定意义上讲限流和熔断也是一种服务降级的手段。

熔断和服务降级主要是针对非核心业务功能,而核心业务如果流程超过预估的峰值,就需要进行限流。

对于限流,选择合理的限流算法很重要,令牌桶算法优势很明显,也是使用最多的限流算法。

在系统设计的时候,这些模式需要配合业务量的预估、性能测试的数据进行相应阈值的配置,而这些阈值最好保存在配置中心,方便实时修改。

https://programmer.csdn.net/646f137d3399b617f0c02aae.html?spm=1001.2101.3001.6650.3&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Eactivity-3-115339664-blog-126461358.235%5Ev39%5Epc_relevant_3m_sort_dl_base4&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Eactivity-3-115339664-blog-126461358.235%5Ev39%5Epc_relevant_3m_sort_dl_base4&utm_relevant_index=6

标签:降级,服务,请求,断路器,熔断,限流
From: https://www.cnblogs.com/beatle-go/p/17911931.html

相关文章

  • openFeign+sentinel 对远程调用熔断降级
    openFeign+sentinel对远程调用熔断降级需求:在member-service-nacos-consumer-80调用某个无效服务时,启动Sentinel的熔断降级机制,能够快速返回响应,而不是使用默认的超时机制(因为超时机制容易线程堆积,从而导致雪崩)异常场景1.两个服务都挂掉由于Customer它要定时从......
  • Redis生产实战-Redis集群故障探测以及降级方案设计
    Redis集群故障探测在生产环境中,如果Redis集群崩溃了,那么会导致大量的请求打到数据库中,会导致整个系统都崩溃,所以系统需要可以识别缓存故障,限流保护数据库,并且启动接口的降级机制降级方案设计我们在系统中操作Redis一般都是通过工具类来进行操作的,假设工具类有两个RedisCache......
  • redis限流
    1、基于Redis的数据结构zset用的redis的zset来计数,score字段寸时间戳,每次请求增加一条数据,并按score移除超时的数据。最后在给整个key1加个过期时间2、基于Redis的令牌桶算法      ......
  • Sentinel——服务降级
    目录简介Sentinel方法级降级Sentinel类级降级OpenFeign类级降级简介服务降级是一种增强用户体验的方式。当用户的请求由于各种原因被拒后,系统返回-一个事先设定好的、用户可以接受的,但又令用户并不满意的结果。这种请求处理方式称为服务降级。Sentinel方法级降级导入依赖......
  • SpringMvc集成开源流量监控、限流、熔断降级、负载保护组件Sentinel
    前言:作者查阅了Sentinel官网、51CTO、CSDN、码农家园、博客园等很多技术文章都没有很准确的springmvc集成Sentinel的示例,因此整理了本文,主要介绍SpringMvc集成SentinelSpringMvc集成Sentinel一、Sentinel介绍随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel......
  • SD3038B原厂高效率恒流限流白光LED驱动芯片IC
    SD3038B原厂高效率恒流限流白光LED驱动芯片IC一、概述SD3038B是一款高效、恒流、限流的白光LED驱动芯片,采用原厂工艺制造,具有高可靠性、低成本、高亮度等特点。该芯片适用于各种LED照明产品,如LED灯具、LED显示屏、LED背光等领域。二、特点高效率:SD3038B采用原厂工艺制造,具有高效率......
  • 基于注解实现 SpringBoot 接口限流
    编写注解类importjava.lang.annotation.Retention;importjava.lang.annotation.Target;importstaticjava.lang.annotation.ElementType.METHOD;importstaticjava.lang.annotation.RetentionPolicy.RUNTIME;@Retention(RUNTIME)@Target(METHOD)public@interfaceAcc......
  • 服务熔断hystrix
    https://cloud.tencent.com/developer/article/2123608 熔断机制概述熔断机制是应对雪崩效应的一种微服务链路保护机制。当扇出链路的某个微服务出错不可用或者响应时间太长时,会进行服务的降级,进而熔断该节点微服务的调用,快速返回错误的响应信息。当检测到该节点微服务调用响......
  • PC8231恒流恒压输出同步降压芯片5V/2.4A内置限流补偿带EN引脚
    一.概述PC8231是一款同步降压转换器,该转换器可驱动输出2.4A负载电流。设计允许PC8231在9V到40V宽输入电压范围内工作。通过将COMP/EN引脚逻辑电平拉低来实现外部关断功能,并进入待机模式。外部补偿使反馈控制环路具有良好的线压调整率和负载调整率,且外围设计灵活。PC8231......
  • PC5600锂电池充电放电管理一体芯片内设限流高耐压输入
    PC5600是一款集成降压转换器、锂电池充电管理、电池充电状态指示的锂电池充放电管理专用芯片,为USB充干电池提供完整的电源解决方案。PC5600充电电流和充电电压可调,支持多种规格锂电池应用,最大充电电流1A。PC5600充电电流根据锂电池温度自动调节,更加安全可靠。PC5600放电输......