【了解】熔断限流

码农沉思录

共 3517字,需浏览 8分钟

 · 2022-11-08


熔断限流降级

熔断、限流、降级都是保持系统稳定运行的策略,但针对的场景有所不同。

架构设计

熔断

服务熔断的作用类似于我们家用的保险丝,当某服务出现不可用或响应超时的情况时,为了防止整个系统出现雪崩,暂时停止对该服务的调用。

854733c2c67a53c379fed00d4ae458bf.webp

上面的解释中有两个很关键的词,一个是暂时,一个是停止。

停止是说,当前服务一旦对下游服务进行熔断,当请求到达时,当前服务不再对下游服务进行调用,而是使用设定好的策略 (如构建默认值)直接返回。

暂时是说,熔断后,并不会一直不再调用下游服务,而是以一定的策略 (如每分钟调用 10 次,若均返回成功,则增大调用量)试探调用下游服务,当下游服务恢复可用时, 自动停止熔断

84e8dcf91c4a63628903a26972732eb9.webp

如上图,当 ServiceD 不可用时,ServiceB 应对 ServiceD 进行熔断。

限流

限流是指上游服务对本服务请求 QPS 超过阙值时,通过一定的策略(如延迟处理、拒绝处理)对上游服务的请求量进行限制,以保证本服务不被压垮,从而持续提供稳定服务。常见的限流算法有滑动窗口、令牌桶、漏桶等。

9180ba6a8b8c72a5ac6142f3caa74da5.webp

如上图,当 ServiceB 对 ServiceD 请求过多时,ServiceD 可以放弃一部分请求,保证自身服务的稳定。

限流指标

TPS

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

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

HPS

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

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

QPS

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

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

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

限流方法

流量计数器

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

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

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

a859c6f3be4262255c84e42837f10637.webp

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

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

0f6ba64496a3247930114e9fabcf397e.webp

滑动时间窗口

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

d02ddff2f6cb70658546c964f034c3d8.webp

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

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

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

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

漏桶算法

漏桶算法的思想如下图:

dc0745e9869dbd3bd048bd244cfd59a4.webp

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

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

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

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

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

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

令牌桶算法

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

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

48487f634d10d45b9c885d4effe73406.webp

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

e28e34824e248eb52e04b10f6edc6d73.webp

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

分布式限流

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

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

388efd9cd56588721833550468feeaa8.webp

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

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

Sentinel你了解多少

降级

降级是指当自身服务压力增大时,采取一些手段,增强自身服务的处理能力,以保障服务的持续可用。比如,下线非核心服务以保证核心服务的稳定、降低实时性、降低数据一致性。

总结

827e59e4a2fc03d9cdeac2af209a6b6a.webp


浏览 20
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报