限流的几种方式

先来描述一下什么是限流

  限流可以认为服务降级的一种,限流就是限制系统的输入和输出流量已达到保护系统的目的。一般来说系统的吞吐量是可以被测算的,为了保证系统的稳定运行,一旦达到的需要限制的阈值,就需要限制流量并采取一些措施以完成限制流量的目的。比如:延迟处理,拒绝处理,或者部分拒绝处理等等。

一般做接口限流主要是为了应对突发流量,避免突发流量拖垮服务。如下面一些场景就有可能发生突发流量

  1. 微博热搜
  2. 恶意刷单
  3. 恶意爬虫
  4. 促销活动
  5. 防止DOS攻击

首先是计算器方式实现

计数器又分固定窗口和滑动窗口

固定窗口计数器:

  就是一个计算器,就是在一个时钟周期(该周期也是可以设置的)内,设定一个访问阈值(就是在刚刚设置的时钟周期内的并发量)。如果并发量超过访问阈值,则开始限流

  存在的问题
  限流不均匀,如下所示我们规定10S内至多10个访问量,但2S内实际上有20个访问量。

  出现流量尖峰。

  

 

 

 

滑动窗口计数器:

  

固定窗口计数器算法由于其存在的临界问题(尖峰问题),统计的精度过低,可能在时间窗口的重置节点处接收大量流量,为解决这个问题,我们引入了滑动窗口算法。

如下图,我们规定访问阈值10,时钟周期是5秒,5秒内超过10次访问量开始限流。该思想就是在任何一个5S内都只有10次访问量。

 

很明显,当滑动窗口的格子划分的越多,那么滑动窗口的滚动就越平滑,限流的统计就会越精确。

  缺点:

  1. 不能解决请求分布不均的问题,即无法平滑流量
  2. 实现更复杂,需要维护时间窗口,占用内存更多,计算时间复杂度也相应变大。

 

 

令牌算法:

  按照固定的速率往漏斗里添加水,(核心思想是所有请求需要再令牌桶获取到令牌才可以处理, 同时有一个服务匀速的往令牌桶装令牌。可以满足一定的突发请求处理,如果超过令牌桶的请求,也会被拒绝)

  过程:

  1. 一直放令牌,如果令牌桶达到上限则丢弃令牌,假设每秒放10个
  2. 可以应对一定程度的流量激增,如此时令牌桶有100个令牌,突然发生200次调用,则此时最开始的100次请求可以正常调用,后续的请求才会以10个/s的速率来调用

  优点:

  1.   解决了固定窗口流量尖峰的问题,确保在任意时刻,过去窗口时间内的请求不会超出阈值。
  2.   可以有效平滑流量,因为令牌桶的令牌是匀速放入的
  3.   相对滑动窗口更节省内存
  4.   适合电商抢购或者微博出现热点事件这种场景,因为在限流的同时可以应对一定的突发流量。如果采用漏桶那样的均匀速度处理请求的算法,在发生热点时间的时候,会造成大量的用户无法访问,         对用户体验的损害比较大。

 

漏桶算法:

  就像一个漏斗,上面口大,下面口小,上面可以一直加很多水的水,但是下面小口的口径是固定的,只会有固定单位的水通过。而且上面水量过大,漏斗放不下  会溢出丢失

  将水和访问量换一下,就明白了  (核心思想就是请求收到后,会先进入漏斗,然后再按照限定速度请求服务,及可以达到限流的目的,也可以保证后台收到的请求都是平稳的。 但是也有一个缺点,就是突然流量的时候,会导致处理时间太长。当然流量更大的时候会被拒绝,这个是正常的)。

    优点:实现相对简单,可以限制服务请求速率,并且稳定在一个常速。

    缺点:对于特发流量处理效率过低,在没有到达服务器负载阈值,也只能串行处理请求。

    实现;限制队列的大小

 

 



 

posted @ 2021-12-15 16:50  老油条666  阅读(989)  评论(0编辑  收藏  举报