熔断,限流,降级

https://www.cnblogs.com/raoshaoquan/articles/6636067.html

https://www.cnblogs.com/DengGao/p/rateLimit.html

https://blog.csdn.net/aa1215018028/article/details/81700796

https://www.jianshu.com/p/3463571febc2

https://www.jianshu.com/p/33f394c0ee2d

https://blog.csdn.net/chunlongyu/article/details/53259014

1 写在前面

1.1 名词解释

consumer表示服务调用方

provider标示服务提供方,dubbo里面一般就这么讲。

下面的A调用B服务,一般是泛指调用B服务里面的一个接口。

1.2 拓扑图

大写字母表示不同的服务,后面的序号表示同一个服务部署在不同机器的实例。

 

2 从微观角度思考

 

2.1 超时(timeout)

在接口调用过程中,consumer调用provider的时候,provider在响应的时候,有可能会慢,如果provider 10s响应,那么consumer也会至少10s才响应。如果这种情况频度很高,那么就会整体降低consumer端服务的性能。

这种响应时间慢的症状,就会像一层一层波浪一样,从底层系统一直涌到最上层,造成整个链路的超时。

所以,consumer不可能无限制地等待provider接口的返回,会设置一个时间阈值,如果超过了这个时间阈值,就不继续等待。

这个超时时间选取,一般看provider正常响应时间是多少,再追加一个buffer即可。

 

2.2 重试(retry)

超时时间的配置是为了保护服务,避免consumer服务因为provider 响应慢而也变得响应很慢,这样consumer可以尽量保持原有的性能。

但是也有可能provider只是偶尔抖动,那么超时后直接放弃,不做后续处理,就会导致当前请求错误,也会带来业务方面的损失。

那么,对于这种偶尔抖动,可以在超时后重试一下,重试如果正常返回了,那么这次请求就被挽救了,能够正常给前端返回数据,只不过比原来响应慢一点。

重试时的一些细化策略:

重试可以考虑切换一台机器来进行调用,因为原来机器可能由于临时负载高而性能下降,重试会更加剧其性能问题,而换一台机器,得到更快返回的概率也更大一些。

 

2.2.1 幂等(idempotent)

如果允许consumer重试,那么provider就要能够做到幂等。

即,同一个请求被consumer多次调用,对provider产生的影响(这里的影响一般是指某些写入相关的操作) 是一致的。

而且这个幂等应该是服务级别的,而不是某台机器层面的,重试调用任何一台机器,都应该做到幂等。

 

2.3 熔断(circuit break)

重试是为了应付偶尔抖动的情况,以求更多地挽回损失。

可是如果provider持续的响应时间超长呢?

如果provider是核心路径的服务,down掉基本就没法提供服务了,那我们也没话说。 如果是一个不那么重要的服务,却因为这个服务一直响应时间长导致consumer里面的核心服务也拖慢,那么就得不偿失了。

单纯超时也解决不了这种情况了,因为一般超时时间,都比平均响应时间长一些,现在所有的打到provider的请求都超时了,那么consumer请求provider的平均响应时间就等于超时时间了,负载也被拖下来了。

而重试则会加重这种问题,使consumer的可用性变得更差。

因此就出现了熔断的逻辑,也就是,如果检查出来频繁超时,就把consumer调用provider的请求,直接短路掉,不实际调用,而是直接返回一个mock的值。

等provider服务恢复稳定之后,重新调用。

 

2.3.1 简单的熔断处理逻辑

目前我们框架有通过注解使用的熔断器,大家可以参考应用在项目中。

 

2.4 限流(current limiting)

上面几个策略都是consumer针对provider出现各种情况而设计的。

而provider有时候也要防范来自consumer的流量突变问题。

这样一个场景,provider是一个核心服务,给N个consumer提供服务,突然某个consumer抽风,流量飙升,占用了provider大部分机器时间,导致其他可能更重要的consumer不能被正常服务。

所以,provider端,需要根据consumer的重要程度,以及平时的QPS大小,来给每个consumer设置一个流量上线,同一时间内只会给A consumer提供N个线程支持,超过限制则等待或者直接拒绝。

 

2.4.1 资源隔离

provider可以对consumer来的流量进行限流,防止provider被拖垮。

同样,consumer 也需要对调用provider的线程资源进行隔离。 这样可以确保调用某个provider逻辑不会耗光整个consumer的线程池资源。

 

2.4.2 服务降级

降级服务既可以代码自动判断,也可以人工根据突发情况切换。

 

2.4.2.1 consumer 端

consumer 如果发现某个provider出现异常情况,比如,经常超时(可能是熔断引起的降级),数据错误,这是,consumer可以采取一定的策略,降级provider的逻辑,基本的有直接返回固定的数据。

 

2.4.2.2 provider 端

当provider 发现流量激增的时候,为了保护自身的稳定性,也可能考虑降级服务。

比如,1,直接给consumer返回固定数据,2,需要实时写入数据库的,先缓存到队列里,异步写入数据库。

 

3 从宏观角度重新思考

宏观包括比A -> B 更复杂的长链路。

长链路就是 A -> B -> C -> D这样的调用环境。

而且一个服务也会多机部署,A 服务实际会存在 A1,A2,A3 …

微观合理的问题,宏观未必合理。

下面的一些讨论,主要想表达的观点是:如果系统复杂了,系统的容错配置要整体来看,整体把控,才能做到更有意义。

 

3.1 超时

如果A给B设置的超时时间,比B给C设置的超时时间短,那么肯定不合理把,A超时时间到了直接挂断,B对C支持太长超时时间没意义。

R表示服务consumer自身内部逻辑执行时间,TAB表示consumer A开始调用provider B到返回的时间 。

那么那么TAB > RB + TBC 才对。

 

3.2 重试

重试跟超时面临的问题差不多。

B服务一般100ms返回,所以A就给B设置了110ms的超时,而B设置了对C的一次重试,最终120ms正确返回了,但是A的超时时间比较紧,所以B对C的重试被白白浪费了。

A也可能对B进行重试,但是由于上一条我们讲到的,可能C确实性能不好,每次B重试一下就OK,但是A两次重试其实都无法正确的拿到结果。

N标示设置的重试次数

修正一下上面section的公式,TAB > RB+TBC * N。

虽然这个公式本身没什么问题,但是,如果站在长链路的视角来思考,我们需要整体规划每个服务的超时时间和重试次数,而不是仅仅公式成立即可。

比如下面情况:

A -> B -> C。

RB = 100ms,TBC=10ms

B是个核心服务,B的计算成本特别大,那么A就应该尽量给B长一点的超时时间,而尽量不要重试调用B,而B如果发现C超时了,B可以多调用几次C,因为重试C成本小,而重试B成本则很高。 so …

 

3.3 熔断

A -> B -> C,如果C出现问题了,那么B熔断了,则A就不用熔断了。

 

3.4 限流

B只允许A以QPS<=5的流量请求,而C却只允许B以QPS<=3的qps请求,那么B给A的设定就有点大,上游的设置依赖下游。

而且限流对QPS的配置,可能会随着服务加减机器而变化,最好是能在集群层面配置,自动根据集群大小调整。

 

3.5 服务降级

服务降级这个问题,如果从整体来操作,

1,一定是先降级优先级地的接口,两权相害取其轻

2,如果服务链路整体没有性能特别差的点,比如就是外部流量突然激增,那么就从外到内开始降级。

3如果某个服务能检测到自身负载上升,那么可以从这个服务自身做降级。

 

3.6 涟漪

A -> B -> C,如果C服务出现抖动,而B没有处理好这个抖动,造成B服务也出现了抖动,A调用B的时候,也会出现服务抖动的情况。

这个暂时的不可用状态就想波浪一样从底层传递到了上层。

所以,从整个体系的角度来看,每个服务一定要尽量控制住自己下游服务的抖动,不要让整个体系跟着某个服务抖动。

 

3.7 级联失败(cascading failure)

系统中有某个服务出现故障,不可用,传递性地导致整个系统服务不可用的问题。

跟上面涟漪(自造词)的区别也就是严重性的问题。

涟漪描述服务偶发的不稳定层层传递,而级联失败基本是导致系统不可用。 一般,前者可能会因为短时间内恢复而未引起重视,而后者一般会被高度重视。

 

3.8 关键路径

关键路径就是,你的服务想正常工作,必须要完整依赖的下游服务链,比如数据库一般就是关键路径里面的一个节点。

尽量减少关键路径依赖的数量,是提高服务稳定性的一个措施。

数据库一般在服务体系的最底层,如果你的服务可以会自己完整缓存使用的数据,解除数据库依赖,那么数据库挂掉,你的服务就暂时是安全的。

 

3.9 最长路径

想要优化你的服务的响应时间,需要看服务调用逻辑里面的最长路径,只有缩短最长时间路径的用时,才能提高你的服务的性能。

原文地址:https://www.cnblogs.com/qianjinyan/p/10816952.html

时间: 2024-11-06 20:13:38

熔断,限流,降级的相关文章

鹰眼跟踪、限流降级,EDAS的微服务解决之道

本文主要从服务化的起源开始讲起,围绕EDAS介绍这些年来,随着阿里庞大的电商技术平台流量和并发不断攀升过程中,中间件的微服务技术面临的一系列挑战及解决方法.同时,也会向读者介绍历次双十一背后,EDAS服务化技术的演进历程. 服务化的起源 微服务的解决之道 海量微服务的挑战 关于作者 以下为精彩内容整理: 服务化的起源 阿里巴巴前期技术现状 当时阿里巴巴技术团队规模有500人左右,整个技术网站使用单一War应用,基于传统应用开发架构,业务每年翻倍增长. 我们面临着非常多的问题: 上百人维护一个核心

微服务熔断限流Hystrix之流聚合

简介 上一篇介绍了 Hystrix Dashboard 监控单体应用的例子,在生产环境中,监控的应用往往是一个集群,我们需要将每个实例的监控信息聚合起来分析,这就用到了 Turbine 工具.Turbine有一个重要的功能就是汇聚监控信息,并将汇聚到的监控信息提供给Hystrix Dashboard来集中展示和监控. 流程 实验 工程说明 工程名 端口 作用 eureka-server 8761 注册中心 service-hi 8762 服务提供者 service-consumer 8763 服

阿里熔断限流Sentinel研究

1. 阿里熔断限流Sentinel学习 1.1. 功能特点 丰富的应用场景:例如秒杀(即突发流量控制在系统容量可以承受的范围).消息削峰填谷.集群流量控制.实时熔断下游不可用应用等 完备的实时监控:Sentinel 同时提供实时的监控功能.您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况. 广泛的开源生态:Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud.Dubbo.gRPC 的整合.您只需要引入相应的依赖

这个注解一次搞定限流与熔断降级:@SentinelResource

在之前的<使用Sentinel实现接口限流>一文中,我们仅依靠引入Spring Cloud Alibaba对Sentinel的整合封装spring-cloud-starter-alibaba-sentinel,就完成了对所有Spring MVC接口的限流控制.然而,在实际应用过程中,我们可能需要限流的层面不仅限于接口.可能对于某个方法的调用限流,对于某个外部资源的调用限流等都希望做到控制.呢么,这个时候我们就不得不手工定义需要限流的资源点,并配置相关的限流策略等内容了. 今天这篇我们就来一起学

Hystrix分布式系统限流、降级、熔断框架(二)

三.Hystrix容错 ???????Hystrix的容错主要是通过添加容许延迟和容错方法,帮助控制这些分布式服务之间的交互. 还通过隔离服务之间的访问点,阻止它们之间的级联故障以及提供回退选项来实现这一点,从而提高系统的整体弹性.Hystrix主要提供了以下几种容错方法: 资源隔离 熔断 降级 1.资源隔离-线程池 2.资源隔离-信号量 线程池和信号量隔离比较 ? 线程切换 支持异步 支持超时 支持熔断 限流 开销 信号量 否 否 否 是 是 小 线程池 是 是 是 是 是 大 ???????

Dubbo学习系列之十(Sentinel之限流与降级)

各位看官,先提个问题,如果让你设计一套秒杀系统,核心要点是啥???我认为有三点:缓存.限流和分离.想当年12306大面积崩溃,还有如今的微博整体宕机情况,感觉就是限流降级没做好,"用有限的资源响应过量请求"——这就是限流降级的核心.限流降级组件,当今开源界应该是Hystrix最为出名,这也得益于SpringCloud的流行,当然,挑战者总是有的,于是Sentinel横空出世,正因实际生产使用中似乎并不多见,所以才有必要拿来一用,不然就脱离了此系列文章的主旨了,就是要见些不一样的风景!

Spring Cloud微服务Sentinel+Apollo限流、熔断实战

在Spring Cloud微服务体系中,由于限流熔断组件Hystrix开源版本不在维护,因此国内不少有类似需求的公司已经将眼光转向阿里开源的Sentinel框架.而以下要介绍的正是作者最近两个月的真实项目实践过程,这中间被不少网络Demo示例级别水文误导过,为了以正视听特将实践过程加以总结,希望能够帮到有类似需要的朋友! 一.Sentinel概述 在基于Spring Cloud构建的微服务体系中,服务之间的调用链路会随着系统的演进变得越来越长,这无疑会增加了整个系统的不可靠因素.在并发流量比较高

限流和降级(下) | 如何打造平台稳定性能力(二)

摘要: 上一期我们谈到了阿里巴巴早期是通过通过在 Nginx 上实现的扩展组件TMD(taobao missile defense淘宝×××防御系统)实现了接入层限流的主要工作,TMD系统可通过域名类限流.cookie限流.黑名单以及一些安全策略等很好的实现了在接入层的限流措施. 上一期我们谈到了阿里巴巴早期是通过通过在 Nginx 上实现的扩展组件TMD(taobao missile defense淘宝×××防御系统)实现了接入层限流的主要工作,TMD系统可通过域名类限流.cookie限流.黑

Sentinel如何通过限流实现服务的高可用性

摘要: 在复杂的生产环境下可能部署着成千上万的服务实例,当流量持续不断地涌入,服务之间相互调用频率陡增时,会产生系统负载过高.网络延迟等一系列问题,从而导致某些服务不可用.如果不进行相应的流量控制,可能会导致级联故障,并影响到服务的可用性,因此如何对高流量进行合理控制,成为保障服务稳定性的关键. 在复杂的生产环境下可能部署着成千上万的服务实例,当流量持续不断地涌入,服务之间相互调用频率陡增时,会产生系统负载过高.网络延迟等一系列问题,从而导致某些服务不可用.如果不进行相应的流量控制,可能会导致级

Spring Cloud Alibaba | Sentinel: 服务限流基础篇

目录 Spring Cloud Alibaba | Sentinel: 服务限流基础篇 1. 简介 2. 定义资源 2.1 主流框架的默认适配 2.2 抛出异常的方式定义资源 2.3 返回布尔值方式定义资源 2.4 注解方式定义资源 2.5 异步调用支持 3. 规则的种类 3.1 流量控制规则 (FlowRule) 3.2 熔断降级规则 (DegradeRule) 3.3 系统保护规则 (SystemRule) 3.4 访问控制规则 (AuthorityRule) Spring Cloud Al