赞
踩
首先维持一个全局计时器,可以是单机的(可Java原子类),也可以是分布式的(可用Redis的incr),计数器可以设置一个阈值,当我们的请求数超过阈值时,就进行限流,拒绝请求(注意,是直接拒绝请求,直接掐断)。
比如:系统设置了能接受100请求的计数器,当我们有一个请求过来的时候,计数器加一;当我们的请求处理完毕后,计数器减一
固定窗口限流原理,是基于计数器的基础上,引入了一个窗口的概念(窗口可以理解为自定义的单位时间段)。在单位时间段内,计数器记录请求的情况。
举例:自定义10秒内(窗口时间为10),限流阈值为5。则在这段时间内,每一个请求打过来,计数器+1;请求处理完毕,计数器-1。倘如在这10秒内,请求计数器总数大于等于5,则直接限流。10秒后,计数器清0,重新开始计数。
譬如,窗口时间大小为1s,限流阈值为100。在0-0.2s内系统接收到了100个请求,则在0.2-1s时倘若请求一直未处理完毕,则所有的请求都会被拒绝,导致服务不可用。
临界值问题,就是当我们的窗口切换的时候,可能会产生两倍于限流阈值的请求量。
滑动窗口限流算法,就是针对固定窗口限流算法的临界值问题,进行改进的算法。
基于固定窗口的限流算法,滑动窗口的限流算法只是在时间窗口内,再记录了每个请求的请求时间,因此其对内存的占用会比较多。其原理根本是将固定窗口限流算法的时间窗口,划分为多个更细的时间窗口。
滑动窗口原理总结:在固定窗口算法基础上,多记录了每个请求的请求时间。以及将固定窗口算法的时间窗口,拆分为更细的多个时间窗口。
虽然说这个问题能够通过设置多个限流规则来处理(比如针对上面案例中的滑动窗口限流算法,再定义一个更小的时间窗口,比如100毫秒内请求数不超过10个),但是设置多个限流规则实在是太麻烦了,而且内存的资源也很珍贵。
其实漏桶算法原理很简单,就像水桶一样,水桶 底部出水的速度是均匀的 ,水桶口可以不管快慢任由水流入,当水桶满了之后,水再流入则会超出容量,进而溢出。溢出的水可以视为请求,就会被限流。
其实针对漏桶算法,溢出的水可以放到MQ中进行补偿,不要把请求完全丢弃。
令牌桶其实是对漏桶算法的改进
限流算法并没有绝对的好劣之分,如何选择合适的限流算法呢?不妨从性能,是否允许超出阈值,落地成本,流量平滑度,是否允许突发流量以及系统资源大小限制多方面考虑。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。