漏桶算法和令牌桶算法实现区别

问题描述?
某天A君突然发现自己的接口请求量突然涨到之前的10倍,没多久该接口几乎不可使用,并引发连锁反应导致整个系统崩溃。如何应对这种情况呢?生活给了我们答案:比如老式电闸都安装了保险丝,一旦有人使用超大功率的设备,保险丝就会烧断以保护各个电器不被强电流给烧坏。同理我们的接口也需要安装上“保险丝”,以防止非预期的请求对系统压力过大而引起的系统瘫痪,当流量过大时,可以采取拒绝或者引流等机制。

1、漏桶算法:水(请求)先进入到漏桶里,漏桶以一定的速度出水,当水流入速度过大会直接溢出(拒绝服务),可以看出漏桶算法能强行限制数据的传输速率

流入:以任意速率往桶中放入水滴。
流出:以固定速率从桶中流出水滴。


用白话具体说明:假设漏斗总支持并发100个最大请求,如果超过100个请求,那么会提示系统繁忙,请稍后再试,数据输出那可以设置1个线程池,处理线程数10个,每秒处理20个请求。
缺点:因为当流出速度固定,大规模持续突发量,无法多余处理,浪费网络带宽
优点:无法击垮服务

漏桶算法和令牌桶算法实现区别

2、令牌桶算法:一个存放固定容量令牌的桶,按照固定速率(每秒/或者可以自定义时间)往桶里添加令牌,然后每次获取一个令牌,当桶里没有令牌可取时,则拒绝服务
令牌桶分为2个动作,动作1(固定速率往桶中存入令牌)、动作2(客户端如果想访问请求,先从桶中获取token)

流入:以固定速率从桶中流入水滴
流出:按照任意速率从桶中流出水滴


技术上使用Google开源工具包Guava提供了限流工具类RateLimiter,该类基于令牌桶算法来完成限流,非常易于使用
优点:支持大的并发,有效利用网络带宽
漏桶算法和令牌桶算法实现区别



create(double permitsPerSecond)根据指定的稳定吞吐率创建RateLimiter,这里的吞吐率是指每秒多少许可数(通常是指QPS,每秒多少查询)

 

create(double permitsPerSecond, long warmupPeriod, TimeUnit unit)根据指定的稳定吞吐率和预热期来创建RateLimiter,这里的吞吐率是指每秒多少许可数(通常是指QPS,每秒多少个请求量),在这段预热时间内,RateLimiter每秒分配的许可数会平稳地增长直到预热期结束时达到其最大速率。(只要存在足够请求数来使其饱和)


提供了两个获取令牌的方法,不带参数表示获取一个令牌.如果没有令牌则一直等待,返回等待的时间(单位为秒),没有被限流则直接返回0.0:

public double acquire();

public double acquire(int permits);

尝试获取令牌,分为待超时时间和不带超时时间两种:

public boolean tryAcquire();
//尝试获取一个令牌,立即返回
public boolean tryAcquire(int permits);
public boolean tryAcquire(long timeout, TimeUnit unit);
//尝试获取permits个令牌,带超时时间
public boolean tryAcquire(int permits, long timeout, TimeUnit unit);
 

参考来源地址:https://blog.csdn.net/m0_37477061/article/details/95313062
http://www.360doc.com/content/18/1003/08/56167096_791542502.shtml
https://www.cnblogs.com/xuwc/p/9123078.html
https://my.oschina.net/hanchao/blog/1833612?from=groupmessage