会使用分布式,那么就说明业务量是较大的,如果不对流量进行限制,很大几率就导致高峰期时机器宕机。而常用的限流算法有四种,这也是所有限流框架实现限流的基础,接下来就通过本文来认识下它们。
计数器限流算法
计数器是限流中最简单的,规定为:在指定周期内累加访问次数,当访问次数达到设定的阈值时,出发限流策略,当进入下一个时间周期时会将访问次数清零
优点:实现简单
临界问题:如图所示,当在8-10秒和10-12秒内分别并发500,虽然没有超过阈值,但如果算8-12秒,则并发数高达1000,已经超过了原先定义的10秒内不超过500的并发量
突刺现象:如果在单位时间10秒内的前100ms,通过了500个请求,则后面的990ms都无法接受任何请求,也就无法应对短时间高并发。
滑动窗口限流算法
为了避免计数器中的临界问题,让限制更加平滑,将固定窗口中分割出多个小时间窗口,分别在每个小的时间窗口中记录访问次数,然后根据时间将窗口往前滑动并删除过期的小时间窗口。
优点:实现相对简单,且没有计数器算法的临界问题
缺点:无法应对短时间高并发(突刺现象)
如图所示,最终只需要统计每个小时间窗口不超过阈值/n && 在滑动窗口范围内的所有的小时间窗口总的计数不超过阈值即可
漏桶限流算法
漏桶限流算法的核心就是, 不管上面的水流速度有多块, 漏桶水滴的流出速度始终保持不变。
实际应用:消息中间件采用的就是漏桶限流的思想
主要作用:
- 控制数据注入网络的速度
- 平滑网络上的突发流量(类似于电容整流)
不足:无法应对突发的并发流量,因为流出速率一直都是恒定的
如图所示,就是一个固定的桶,桶上半部分没有限制流入速率(满了会溢出),但出水速率受限于孔的大小,也就是不管多少请求,最后给服务的请求数量的速率是恒定的,多余的请求将无法通过在桶内等待
令牌桶限流算法
令牌桶是**网络流量整形(Traffic Shaping)和速率限制(Rate Limiting)**中最常使用的一种算法
速度恒定、令牌桶大小固定,如果令牌桶被填满,则会丢弃生成的令牌,如果桶内没有令牌则出现限流策略
优点:可以像漏桶那样匀速,也可以像计数器那样突发处理
基本过程:
- 每进来一个请求,都在桶里获取一个令牌
- 如果有令牌,则拿着令牌通过
- 如果没有令牌,则不允许请求通过
几种情况:
- 请求速度 > 令牌生成速度:当令牌被取空后会被限流
- 请求速度 = 令牌生成速度:流量处于平稳状态
- 请求速度 < 令牌生成速度:请求可被正常处理,多余的令牌直接丢弃
总结
不同的限流算法都有其应用场景,并不是说令牌桶算法就最好,计数器算法就最差,具体可以依据业务的并发情况进行选择,比如业务是否会有突发流量?是否对流量恒定有要求?最好是根据业务特点选择不同的限流算法。