限流的目标与模式

2023-04-11 19:16:25 浏览数 (1)

限流

根据什么限流

要不要控制流量、要控制哪些流量、控制力度要有多大,等等,这些操作都没法在系统设计阶段静态地给出确定的结论,必须根据系统此前一段时间的运行状况,甚至未来一段时间的预测情况来动态决定。

ps:针对突然暴增的ip的流量,一般都属于黑客攻击,直接封掉增加时间梯度封禁即可,

具体如何限流

常用的服务限流算法和设计模式

与容错模式类似,对于具体如何进行限流,业界内也有一些常见、常用、被实践证明有效的设计模式可以参考使用,包括流量计数器、滑动时间窗、漏桶和令牌桶这四种,下面我们一起来看看。

超额流量如何处理?

否决式限流:返回失败或者服务降级。

阻塞式限流:排队等待

流量统计指标

每秒事务数(Transactions per Second,TPS)

每秒请求数(Hits per Second,HPS)

每秒查询数(Queries per Second,QPS)

目前来说,主流系统大多倾向于使用 HPS 作为首选的限流指标,因为它相对容易观察统计,而且能够在一定程度上反映系统当前以及接下来一段时间的压力。

根据系统的实际需要,哪怕完全不选择基于调用计数的指标都是有可能的。我举个简单的例子,下载、视频、直播等 I/O 密集型系统,往往会把每次请求和响应报文的大小作为限流指标,而不是调用次数。

分布式限流

之前提过的种种限流算法和模式全部是针对整个系统的限流,总是有意无意地假设或默认系统只提供一种业务操作,或者所有业务操作的消耗都是等价的,并不涉及不同业务请求进入系统的服务集群后,分别会调用哪些服务、每个服务节点处理能力有何差别等问题。

另外,这些限流算法直接使用在单体架构的集群上确实是完全可行的,但到了微服务架构下,它们就最多只能应用于集群最入口处的网关上,对整个服务集群进行流量控制,而无法细粒度地管理流量在内部微服务节点中的流转情况。

所以,我们把前面介绍的限流模式都统称为单机限流,把能够精细控制分布式集群中每个服务消耗量的限流算法称为分布式限流。

你可能要问,这两种限流算法在实现上的核心差别是什么呢?

答案是,要看二者是如何管理限流的统计指标的。

单机限流很好办,指标都是存储在服务的内存当中;

而分布式限流的目的是要让各个服务节点的协同限流。无论是将限流功能封装为专门的远程服务,还是在系统采用的分布式框架中有专门的限流支持,都需要把每个服务节点的内存中的统计数据给开放出来,让全局的限流服务可以访问到才行。

一种常见的简单分布式限流方法,是将所有服务的统计结果都存入集中式缓存(如 Redis)中,以实现在集群内的共享,并通过分布式锁、信号量等机制,解决这些数据在读写访问时的并发控制问题。

原本用于单机的限流模式,理论上也是可以应用于分布式环境中的,可是它的代价也显而易见:每次服务调用都必须要额外增加一次网络开销,所以这种方法的效率肯定是不高的,当流量压力大的时候,限流本身反倒会显著降低系统的处理能力。

货币化限流

因此为了缓解这里产生的性能损耗,一种可以考虑的办法是在令牌桶限流模式的基础上,进行“货币化改造”改造。即不把令牌看作是只有准入和不准入的“通行证”,而把它看作是数值形式的“货币额度”。

当请求进入集群时,首先在 API 网关处领取到一定数额的“货币”,为了体现不同等级用户重要性的差别,他们的额度可以有所差异,比如让 VIP 用户的额度更高甚至是无限的。

这里我们将用户 A 的额度表示为 QuanityA。由于任何一个服务在响应请求时,都需要消耗集群中一定量的处理资源,所以在访问每个服务时都要求消耗一定量的“货币”。

假设服务 X 要消耗的额度表示为 CostX,那当用户 A 访问了 N 个服务以后,他剩余的额度 LimitN 就会表示为:

  • LimitN = QuanityA - ∑NCostX

此时,我们可以把剩余额度 LimitN 作为内部限流的指标,规定在任何时候,只要剩余额度 LimitN 小于等于 0 时,就不再允许访问其他服务了。另外,这时还必须先发生一次网络请求,重新向令牌桶申请一次额度,成功后才能继续访问,不成功则进入降级逻辑。除此之外的任何时刻,即 LimitN 不为 0 时,都无需额外的网络访问,因为计算 LimitN 是完全可以在本地完成的。

这种基于额度的限流方案,对限流的精确度会有一定的影响,比如可能存在业务操作已经进行了一部分服务调用,却无法从令牌桶中再获取到新额度,因“资金链断裂”而导致业务操作失败的情况。这种失败的代价是比较高昂的,它白白浪费了部分已经完成了的服务资源,但总体来说,它仍然是一种在并发性能和限流效果上,都相对折衷可行的分布式限流方案。

小结

这节课,学习了限流的目标与指标这两项概念性的内容,现在你可以根据系统的服务和流量特征,来事先做好系统开发设计中针对流量的规划问题了。

对于分布式系统容错的设计,是必须要有且无法妥协的措施。但限流与容错不一样,做分布式限流从不追求“越彻底越好”,我们往往需要权衡方案的代价与收益。

0 人点赞