请求限流算法有哪些?分别面向什么应用场景?

所谓限流即流量限制,解决的是在流量高峰期或者流量突增时服务的可用性问题。我们希望把流量限制在该服务所能接受的合理范围之内,不至于让服务被高流量击垮,如下图所示。


针对上图,业界关于如何实现限流也有一些常见的方法,这些方法可以分成两大类,即流量控制和流量整形,如下图所示。


上图展示了用于流量控制的单位时间内调用量和并发调用限流算法,以及用于流量整形的漏桶算法以及令牌桶算法限流。下面我们对这些方法逐一进行展开。

单位时间内调用量限流的基本思想非常简单,就是控制一定时间内的请求量大小,如果这个请求量在合理的访问阈值内,我们就认为能起到限流的效果。针对这种实现方法,我们需要做的就是使用一个计数器(Counter)统计单位时间内某个服务的访问量。一旦访问量超过了所设定的阈值,则该单位时间段内不允许服务继续响应请求,或者把接下来的请求放入队列中等待下一个单位时间段继续执行。计数器的执行效果如下图所示。


当然,计数器需要在一个单位时间结束时对累积的请求量进行清零。计数器算法可以说是限流算法里最简单也是最容易实现的一种算法,但是也有一个十分致命的问题,那就是临界问题。我们来展示一下这个问题。

我们设定单位时间是10秒钟,阈值同样是10。假设服务请求在第10秒快要结束的时候一次发送10个请求,这时候一个单位时间结束,计数器清零。那么在第11秒开始的瞬间原则上又可以发送10个请求,这样在这一段很短的时间之内,服务A相当于接收到了20个请求,超过了限流的阈值,可能导致服务失败。整个过程如下图所示。


为了解决普计数器的临界问题,我们可以采用滑动窗口(Sliding Window)来进行限流。在滑动窗口中,我们把单位时间设置为一个时间窗口,然后把时间窗口进行进一步划分。比方说我们可以把10秒这个单位时间划分成10个时间格,这样每格代表1秒钟。然后每过1秒,时间窗口就会往右滑动一格。每一个格子都有自己独立的计数器,如下图所示。


那么滑动窗口是怎么解决临界问题的呢?我们可以看到在上图中,第10秒快要结束时到达的10个请求会落在10号格子中,而第11秒刚开始时到达的10个请求会落在11号格子中。而当第10秒结束时,时间窗口会往右移动一格,那么此时时间窗口内的总请求数量一共是10+10=20个,超过了限定的10个,所以能够检测出来触发了限流。

从这个角度讲,我们可以认为计数器算法实际上是滑动窗口算法的一种特例,只是它没有对时间窗口做进一步划分。由此可见,当滑动窗口的格子划分的越多,那么滑动窗口的滚动就越平滑,限流的统计就会越精确。

另一种常见的流量控制手段就是并发调用限流。比如说,我们需要限制方法被调用的并发数不能超过100(同一时间并发数),则我们可以使用并发调用限流机制。在实现过程中,我们往往可以引入信号量(Semaphore)来完成这一目标。信号量也是一种计数器,用来保护一个或者多个共享资源的访问,它可以用来控制同时访问特定资源的线程数量,通过协调各个线程以保证合理的使用资源。

介绍完用于实现流量限制的常见做法之后,我们在看漏桶算法,该算法是网络流量整形的常用算法之一。顾名思义,漏桶算法有点像我们生活中用到的漏斗,液体倒进去以后,总是从下端的小口中以固定速率流出,也就是说不管突发流量有多大,漏桶都保证了流量的恒定速率输出。如果我们把服务调用量看做是液体,那么不管服务请求的变化多么剧烈,通过漏桶算法进行整形之后只会输出固定的服务请求,如下图所示。


上图中,我们看到请求1~9以不同的速率进入漏桶,而输出的则是固定速率的请求1~5,剩余的请求则会继续留在漏桶中。请注意,漏桶本身的容量肯定也不是无限大的,所以当桶中的请求数量超过了桶的容量,新来的请求也只能被丢弃掉了。例如,假设上图中漏桶的容量为3,那么请求6~8会保存在桶中,而请求9就会被丢弃。

在很多应用场景中,除了要求能够限制请求的平均响应速率外,还要求允许某种程度的突发传输。这时候漏桶算法可能就不合适了,令牌桶算法更为适合,令牌桶算法从某种程度上来说是漏桶算法的一种改进,它的结构如下图所示。


正如上图所示,令牌桶算法的原理是系统会以一个恒定的速度往桶里放入令牌。如果请求需要被处理,则先从桶里获取一个令牌,当桶里没有令牌可取时,则拒绝服务。而如果某一时间点上桶内存放着很多令牌,那么也就可以在这一时间点上响应很多的请求,因此服务请求的输入和输出都可以是变速的。通过以上分析,我们明白令牌桶算法和漏桶算法的主要区别在于漏桶算法能够强行限制数据的传输速率,而令牌桶算法能够在限制数据平均传输速率的同时还允许某种程度的突发传输。

  • 16
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值