目录

一、服务雪崩

二、服务限流

1、限流指标

1)TPS

2)HPS

3)QPS

2、限流方法

1)流量计数器

2)滑动时间窗口

3)漏桶算法

4)令牌桶算法

5)分布式限流

6)hystrix限流

三、服务熔断

1、基本介绍

2、断路器的状态

四、服务降级

1、基本介绍

2、使用hystrix降级

1 )异常降级

2)调用超时降级

五、总结

1、熔断和降级的相同点

2、熔断和降级的不同点

3、服务限流总结


一、服务雪崩

在微服务之间进行服务调用是由于某一个服务故障,导致级联服务故障的现象,称为雪崩效应。雪崩效应描述的是提供方不可用,导致消费方不可用并将不可用逐渐放大的过程。

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

如下图:

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

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

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

下面我们来聊一聊系统容错中的限流、熔断和服务降级。

二、服务限流

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

1、限流指标

1)TPS

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

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

2)HPS

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

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

3)QPS

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

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

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

2、限流方法

1)流量计数器

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

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

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

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

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

2)滑动时间窗口

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

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

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

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

  • 流量超过就必须抛弃或者走降级逻辑
  • 对流量控制不够精细,不能限制集中在短时间内的流量,也不能削峰填谷

3)漏桶算法

漏桶算法的思想如下图:

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

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

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

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

  • 漏桶的大小,如果太大,可能给服务端带来较大处理压力,太小可能会有大量请求被丢弃。
  • 漏桶给服务端的请求发送速率。
  • 使用缓存请求的方式,会使请求响应时间变长。

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

4)令牌桶算法

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

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

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

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

5)分布式限流

如果在分布式系统场景下,上面介绍的4种限流算法是否还适用呢?

以令牌桶算法为例,假如在电商系统中客户下了一笔订单,如下图:

如果我们把令牌桶单独保存在一个地方(比如redis中)供整个分布式系统用,那客户端在调用组合服务,组合服务调用订单、库存和账户服务都需要跟令牌桶交互,交互次数明显增加了很多。

有一种改进就是客户端调用组合服务之前首先获取四个令牌,调用组合服务时减去一个令牌并且传递给组合服务三个令牌,组合服务调用下面三个服务时依次消耗一个令牌。

6)hystrix限流

hystrix可以使用信号量和线程池来进行限流。

信号量限流

hystrix可以使用信号量进行限流,比如在提供服务的方法上加下面的注解。这样只能有20个并发线程来访问这个方法,超过的就被转到了errMethod这个降级方法。

@HystrixCommand(commandProperties= {@HystrixProperty(name="execution.isolation.strategy", value="SEMAPHORE"),@HystrixProperty(name="execution.isolation.semaphore.maxConcurrentRequests", value="20")},fallbackMethod = "errMethod"
)

线程池限流

hystrix也可以使用线程池进行限流,在提供服务的方法上加下面的注解。

@HystrixCommand(commandProperties = {@HystrixProperty(name = "execution.isolation.strategy", value = "THREAD")},threadPoolKey = "createOrderThreadPool",threadPoolProperties = {@HystrixProperty(name = "coreSize", value = "20"),@HystrixProperty(name = "maxQueueSize", value = "100"),@HystrixProperty(name = "maximumSize", value = "30"),@HystrixProperty(name = "queueSizeRejectionThreshold", value = "120")},fallbackMethod = "errMethod"
)

这里要注意:在 java 的线程池中,如果线程数量超过 coreSize ,创建线程请求会优先进入队列,如果队列满了,就会继续创建线程直到线程数量达到 maximumSize ,之后走拒绝策略。

但在hystrix配置的线程池中多了一个参数 queueSizeRejectionThreshold ,如果 queueSizeRejectionThreshold  < maxQueueSize ,队列数量达到 queueSizeRejectionThreshold 就会走拒绝策略了,因此 maximumSize 失效了。如果 queueSizeRejectionThreshold  >  maxQueueSize ,队列数量达到 maxQueueSize 时, maximumSize 是有效的,系统会继续创建线程直到数量达到 maximumSize 。Hytrix线程池设置坑[2]

三、服务熔断

1、基本介绍

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

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

通过向调用方法返回一个符合预期的、可处理的备选响应(FallBack),而不是⻓时间的等待或者抛出调用方法无法处理的异常,这样就保证了服务调用方的线程不会被⻓时间占用,避免故障在分布式系统中蔓延,乃至雪崩。如果目标服务情况好转则恢复调用。

服务熔断是解决服务雪崩的重要手段。

2、断路器的状态

断路器有3种状态:

  • CLOSED :默认状态。断路器观察到请求失败比例没有达到阈值,断路器认为被代理服务状态良好。
  • OPEN :断路器观察到请求失败比例已经达到阈值,断路器认为被代理服务故障,打开开关,请求不再到达被代理的服务,而是快速失败。
  • HALF OPEN :断路器打开后,为了能自动恢复对被代理服务的访问,会切换到半开放状态,去尝试请求被代理服务以查看服务是否已经故障恢复。如果成功,会转成 CLOSED 状态,否则转到 OPEN 状态。

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

四、服务降级

1、基本介绍

服务压力剧增的时候根据当前的业务情况及流量对一些服务和⻚面有策略的降级,以此缓解服务器的压力,以保证核心任务的进行。同时保证部分甚至大部分任务客户能得到正确的响应。也就是当前的请求处理不了了或者出错了,给一个默认的返回。

比如贴吧类型的网站,当服务器吃不消的时候,可以选择把发帖功能关闭,注册功能关闭,改密码,改头像这些都关了,为了确保登录和浏览帖子这种核心的功能。

一句话就是,服务降级是对非核心、非关键的服务进行降级,保证系统核心服务正常运行。

2、使用hystrix降级

1 )异常降级

hystrix降级时可以忽略某个异常,在方法上加上 @HystrixCommand 注解:

下面的代码定义降级方法是 errMethod ,对 ParamErrorException 和 BusinessTypeException 这两个异常不做降级处理。

@HystrixCommand(fallbackMethod = "errMethod",ignoreExceptions = {ParamErrorException.class, BusinessTypeException.class}
)

2)调用超时降级 

下面的方法是调用第三方接口 3 秒未收到响应就降级到 errMethod 方法。

@HystrixCommand(commandProperties = {@HystrixProperty(name="execution.timeout.enabled", value="true"),@HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds", value="3000"),},fallbackMethod = "errMethod"
)

五、总结

熔断必会触发降级,所以熔断也是降级一种。区别在于熔断是对调用链路的保护,而降级是对系统过载的一种保护处理。

1、熔断和降级的相同点

  • 目的很一致,都是从可用性可靠性着想,为防止系统的整体缓慢甚至崩溃,采用的技术手段
  • 最终表现类似,对于两者来说,最终让用户体验到的是某些功能暂时不可达或不可用
  • 粒度一般都是服务级别,当然,业界也有不少更细粒度的做法,比如做到数据持久层(允许查询,不允许增删改)
  • 自治性要求很高,熔断模式一般都是服务基于策略的自动触发,降级虽说可人工干预,但在微服务架构下,完全靠人显然不可能,开关预置、配置中心都是必要手段(sentinel)

2、熔断和降级的不同点

  • 触发原因不太一样,服务熔断一般是某个服务(下游服务)故障引起,而服务降级一般是从整体负荷考虑
  • 管理目标的层次不太一样,熔断其实是一个框架级的处理,每个微服务都需要(无层级之分),而降级一般需要对业务有层级之分(比如降级一般是从最外围服务边缘服务开始)

3、服务限流总结

上面说的两个算是请求过来我们都受理了,这个限流就更狠了,直接跟请求说对不起再见!也就是系统规定了多少承受能力,只允许这么些请求能过来,其他的请求就说再见了。

参考文章:

面试官:说说降级、熔断、限流 - 掘金 (juejin.cn)

10张图带你彻底搞懂限流、熔断、服务降级 - 腾讯云开发者社区-腾讯云 (tencent.com)

(1条消息) 服务雪崩、服务熔断、服务降级_薛伟同学的博客-CSDN博客_服务雪崩服务降级服务熔断

12张图带你彻底搞懂服务限流、熔断、降级、雪崩相关推荐

  1. 10分钟带你彻底搞懂服务限流和服务降级

    文章目录 十分钟搞懂系列 服务限流 计数器法 滑动窗口法 漏桶算法 令牌桶算法 服务降级 十分钟搞懂系列 序号 标题 链接 1 10分钟带你彻底搞懂企业服务总线 https://blog.csdn.n ...

  2. 秒杀项目之网关服务限流熔断降级分布式事务

    目录 一.网关服务限流熔断降级 二.Seata--分布式事务 2.1 分布式事务基础 2.1.1 事务 2.1.2 本地事务 2.1.3 分布式事务 2.1.4 分布式事务场景 2.2 分布式事务解决 ...

  3. 哨兵 双向 java_SpringCloud微服务:Sentinel哨兵组件,管理服务限流和降级

    一.基本简介 1.概念描述 Sentinel 以流量为切入点,从流量控制.熔断降级.系统负载保护等多个维度保护服务的稳定性.包括核心的独立类库,监控台,丰富的使用场景验证.(这似乎是阿里开源组件的一贯 ...

  4. 儒猿秒杀季!微服务限流熔断技术源码剖析与架构设计

    疯狂秒杀季:49元秒杀 原价 299元 的 <微服务限流熔断技术源码剖析与架构设计课> 今天 上午11点,仅 52 套,先到先得! === 课程背景 === 成为一名架构师几乎是每个程序员 ...

  5. 通过这12张手绘图,搞懂什么是微服务架构

    点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 作者 | tengshe789 来源 | juejin. ...

  6. 10张图带你彻底搞懂什么是限流、熔断、服务降级

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

  7. 十分钟搞懂Java限流及常见方案

    点击关注公众号:互联网架构师,后台回复 2T获取2TB学习资源! 上一篇:Alibaba开源内网高并发编程手册.pdf 文章目录 限流基本概念 QPS和连接数控制 传输速率 黑白名单 分布式环境 限流 ...

  8. 一文搞懂Nginx限流(简单实现)

    Nginx现在已经是最火的负载均衡之一,在流量陡增的互联网面前,接口限流也是很有必要的,尤其是针对高并发的场景.Nginx的限流主要是两种方式:限制访问频率和限制并发连接数. 限流(rate limi ...

  9. java服务限流_SpringCloud微服务:Sentinel哨兵组件,管理服务限流和降级

    一.基本简介 1.概念描述 sentinel 以流量为切入点,从流量控制.熔断降级.系统负载保护等多个维度保护服务的稳定性.包括核心的独立类库,监控台,丰富的使用场景验证.(这似乎是阿里开源组件的一贯 ...

最新文章

  1. 【计算机网络】传输层 : TCP 拥塞控制 ( 慢开始 | 拥塞避免 | 快重传 | 快恢复 )
  2. 必会重构技巧(三):提取接口
  3. 携程在线风控系统架构
  4. 天梯赛 L1-009 N个数求和 (20 分)
  5. array_sum的用法
  6. 点歌机显示一直弹出连接服务器,点歌机老是显示正在连接云服务器
  7. 海康威视mp4html播放器,videoJS 网页视频播放器支持MP4
  8. 防范ARP网关欺骗, ip mac双向绑定脚本
  9. 计算机输出科学计数法,C语言里要对输出的结果用科学计数法表示保留三位有效数字应该怎么写啊?...
  10. 【DS】数据结构八股文英文版(1)
  11. LiveData setValue和postValue的区别及详解
  12. 边缘检测-HED-RCF
  13. asp.net+mvc+html辅助,ASP.NET MVC使用Ajax的辅助的解决方法
  14. Pycharm Professional Edition 激活码(license),有效期至2018年01月30日
  15. 【注意力机制】BAM: Bottleneck Attention Module论文理解
  16. Window设置开机自启软件的几种方式
  17. 简单题我重拳出击,困难题我唯唯诺诺
  18. 最美中国字|“粘”字书写技巧这样写,保证工整又好看!
  19. eDairy-我的白日梦
  20. win10修改桌面图标大小

热门文章

  1. numpy 并行计算实现kmeans操作
  2. 读书笔记-精准努力-关于生活的一些建议
  3. 网站服务器或者代理查找失败,新的网站收录最快的方法,没有之一 - 搜外SEO问答...
  4. Linux系统查看系统安装时间
  5. 单端反激式开关电源 UC3843应用
  6. opencv实现图片中文字识别并切割
  7. 逻辑回归函数求偏导及Sigmoid函数求偏导
  8. 教你如何设置单行或多行文本超出省略号
  9. OpenCv图像处理之图像归一化
  10. php远程连接真机实现,搭建nextcloud私有云存储网盘的教程详解