当前位置:   article > 正文

【限流算法】大白话阐述四种限流算法

限流算法

计数器

计数限流原理

首先维持一个全局计时器,可以是单机的(可Java原子类),也可以是分布式的(可用Redis的incr),计数器可以设置一个阈值,当我们的请求数超过阈值时,就进行限流,拒绝请求(注意,是直接拒绝请求,直接掐断)。

比如:系统设置了能接受100请求的计数器,当我们有一个请求过来的时候,计数器加一;当我们的请求处理完毕后,计数器减一

固定窗口限流原理

固定窗口限流原理,是基于计数器的基础上,引入了一个窗口的概念(窗口可以理解为自定义的单位时间段)。在单位时间段内,计数器记录请求的情况。

  • 当前处理的请求总数少于限流阈值时,允许访问,计数器+1
  • 当前处理的请求总数大于等于限流阈值时,拒绝访问
  • 当前时间过了指定的时间窗口后,计数器清0

举例:自定义10秒内(窗口时间为10),限流阈值为5。则在这段时间内,每一个请求打过来,计数器+1;请求处理完毕,计数器-1。倘如在这10秒内,请求计数器总数大于等于5,则直接限流。10秒后,计数器清0,重新开始计数。

优点
  • 实现简单粗暴
缺点
  • 假如设置阈值为1000,一开始的时候,计数器为0,突然有1000个请求打进来,这时候虽然计数器触发了限流,但是对于系统来说1000并发处理的压力还是很大的。这固然会导致后面的请求会一直被限流,而导致用户操作发出的请求一直无法响应,就跟系统挂了一样。

譬如,窗口时间大小为1s,限流阈值为100。在0-0.2s内系统接收到了100个请求,则在0.2-1s时倘若请求一直未处理完毕,则所有的请求都会被拒绝,导致服务不可用。

  • 临界值问题:倘若定义窗口时间为1s,限流阈值10。在0.8s到1s期间,发出了10个请求,第一个窗口时间结束;第二个窗口时间开始计数,在1s到1.2s期间,再发10个请求。则在0.8s到1.2s期间,总请求数达到了20。虽然说在单个窗口时间内没有超过限流阈值,但是在0.8s到1.2s期间,我们定义的单位窗口时间内限流阈值为10的条件已经不满足了。

临界值问题,就是当我们的窗口切换的时候,可能会产生两倍于限流阈值的请求量。

在这里插入图片描述

滑动窗口

滑动窗口限流算法,就是针对固定窗口限流算法的临界值问题,进行改进的算法。

原理

基于固定窗口的限流算法,滑动窗口的限流算法只是在时间窗口内,再记录了每个请求的请求时间,因此其对内存的占用会比较多。其原理根本是将固定窗口限流算法的时间窗口,划分为多个更细的时间窗口。

  • 假设我们定义时间窗口为1分钟。那么滑动窗口就会把时间窗口进行划分,划分6格,则每格时间窗口代表10秒。
  • 当请求进来时,就会记录当前的请求时间。当前请求时间 - 当前请求时间往前推10s的时间,这个时间段就是滑动窗口算法的时间窗口
  • 当滑动窗口算法的时间窗口,计数器统计的总数大于阈值,则限流。否则请求通过
    在这里插入图片描述

滑动窗口原理总结:在固定窗口算法基础上,多记录了每个请求的请求时间。以及将固定窗口算法的时间窗口,拆分为更细的多个时间窗口。

优点
  • 解决了固定窗口算法的临界值问题,避免了固定窗口算法在切换窗口时请求总量可能为阈值两倍的问题
缺点
  • 仍无法解决短时间内高并发的场景,比如限流阈值是100,时间窗口定位为10s,倘若在1s内就把100个请求打满了,那2-9s期间服务器一直无法处理请求。因此处理流量突增的方式还是不够平滑。

虽然说这个问题能够通过设置多个限流规则来处理(比如针对上面案例中的滑动窗口限流算法,再定义一个更小的时间窗口,比如100毫秒内请求数不超过10个),但是设置多个限流规则实在是太麻烦了,而且内存的资源也很珍贵。

漏桶

原理

其实漏桶算法原理很简单,就像水桶一样,水桶 底部出水的速度是均匀的 ,水桶口可以不管快慢任由水流入,当水桶满了之后,水再流入则会超出容量,进而溢出。溢出的水可以视为请求,就会被限流。
在这里插入图片描述

优、缺点
  • 其可以使流量更加平滑(抛出一个问题:如何定义平滑?),相比窗口算法平滑一些,但是又不够平滑。因为针对突然大量的情况下,由于底部出口是固定速率流出水的,所以针对高并发场景还是不够理想。

其实针对漏桶算法,溢出的水可以放到MQ中进行补偿,不要把请求完全丢弃。

令牌桶

原理

令牌桶其实是对漏桶算法的改进

  • 有一个令牌管理员,定速的往令牌桶中丢令牌
  • 当令牌桶满了的时候,再往令牌桶丢令牌,就会溢出随之丢弃多余的令牌
  • 倘若请求过来了,都会先去令牌桶获取令牌。拿到了令牌才能过处理相关业务
  • 倘若拿不到令牌,则直接拒绝请求

在这里插入图片描述

优点
  • 起限流作用的同时,还能够支撑突然性地高并发场景。比如突然有100个请求打了进来,此时令牌桶是满的(里面有100个令牌),那么我们这100个请求就能过立马拿到令牌进行处理,而不像漏桶算法一样均匀地处理请求(底部均匀漏水)。因此令牌桶针对流量突增的场景表现更佳

总结

限流算法并没有绝对的好劣之分,如何选择合适的限流算法呢?不妨从性能,是否允许超出阈值,落地成本,流量平滑度,是否允许突发流量以及系统资源大小限制多方面考虑。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/274634
推荐阅读
相关标签
  

闽ICP备14008679号