相关历史文章(阅读本文之前,您可能需要先看下之前的系列)
国内最全的Spring Boot系列之三
版本号命名的前世今生- 值得收藏 - 第299篇
「世界上最好的学习法:费曼学习法」
高并发,不怕不怕「限流算法第一把法器:计数器法」 - 第300篇
精度不够,滑动时间来凑「限流算法第二把法器:滑动时间窗口算法」- 第301篇
没有预热,不叫高并发「限流算法第三把法器:令牌桶算法」- 第302篇
悟纤:师傅你溢了嘛?
师傅:我又不是水桶,我溢啥溢。
悟纤:反正师傅明白,不承认徒儿也没有办法了。
师傅:看来你是欠揍了。
悟纤:(内心世界:赶紧转移下话题,不然要挨揍了)师傅,我看那个限流算法有一个水桶算法。
师傅:这名字哪里听来的,是漏桶算法,今天咱们来聊聊这个漏桶算法。
一、漏桶算法
漏桶算法,又称leaky bucket。为了理解漏桶算法,我们看一下对于该算法的示意图:
从图中我们可以看到,整个算法其实十分简单。首先,我们有一个固定容量的桶,有水流进来,也有水流出去。对于流进来的水来说,我们无法预计一共有多少水会流进来,也无法预计水流的速度。但是对于流出去的水来说,这个桶可以固定水流出的速率。而且,当桶满了之后,多余的水将会溢出。
我们将算法中的水换成实际应用中的请求,我们可以看到漏桶算法天生就限制了请求的速度。当使用了漏桶算法,我们可以保证接口会以一个常速速率来处理请求。所以漏桶算法天生不会出现临界问题。
漏桶算法可以粗略的认为就是注水漏水过程,往桶中以一定速率流出水,以任意速率流入水,当水超过桶流量则丢弃,因为桶容量是不变的,保证了整体的速率。
二、漏桶算法小栗子
来看个小栗子:
public class LeakyBucket {
public long timeStamp = System.currentTimeMillis(); // 当前时间
public long capacity; // 桶的容量
public long rate; // 水漏出的速度
public long water; // 当前水量(当前累积请求数)
public boolean grant() {
long now = System.currentTimeMillis();
// 先执行漏水,计算剩余水量
water = Math.max(0, water - (now - timeStamp) * rate);
timeStamp = now;
if ((water + 1) < capacity) {
// 尝试加水,并且水还未满
water += 1;
return true;
} else {
// 水满,拒绝加水
return false;
}
}
}
说明:
(1)未满加水:通过代码 water +=1进行不停加水的动作。
(2)漏水:通过时间差来计算漏水量。
(3)剩余水量:总水量-漏水量。
三、算法对比
3.1 计数器 VS 滑动窗口:
计数器算法是最简单的算法,可以看成是滑动窗口的低精度实现。滑动窗口由于需要存储多份的计数器(每一个格子存一份),所以滑动窗口在实现上需要更多的存储空间。也就是说,如果滑动窗口的精度越高,需要的存储空间就越大。
3.2漏桶算法 VS 令牌桶算法:
漏桶算法和令牌桶算法最明显的区别是令牌桶算法允许流量一定程度的突发。因为默认的令牌桶算法,取走token是不需要耗费时间的,也就是说,假设桶内有100个token时,那么可以瞬间允许100个请求通过。
令牌桶算法由于实现简单,且允许某些流量的突发,对用户友好,所以被业界采用地较多。当然我们需要具体情况具体分析,只有最合适的算法,没有最优的算法。
四、悟纤小结
师傅:通过最近的一段时间,咱们也学习了不少限流算法,徒儿你和大家做个下节吧
(1)常用限流算法:滑动窗口算法(也叫滑动时间窗口算法)、令牌桶算法、漏桶算法。
(2)Sentinel限流算法
流控效果就是限流算法的配置。
快速失败 – 滑动时间窗口算法;
Warm Up – 令牌桶算法;
排队等待 - 漏桶算法。
(3)流量控制组件:Hystrix、Sentinel
SentinelVS Hystrix:
还有一个框架是resilience4j:
我就是我,是颜色不一样的烟火。
我就是我,是与众不同的小苹果。
学院中有Spring Boot相关的课程:
à悟空学院:https://t.cn/Rg3fKJD
SpringBoot视频:http://t.cn/A6ZagYTi
Spring Cloud视频:http://t.cn/A6ZagxSR
SpringBoot Shiro视频:http://t.cn/A6Zag7IV
SpringBoot交流平台:https://t.cn/R3QDhU0
SpringData和JPA视频:http://t.cn/A6Zad1OH
SpringSecurity5.0视频:http://t.cn/A6ZadMBe
Sharding-JDBC分库分表实战:http://t.cn/A6ZarrqS
分布式事务解决方案「手写代码」:http://t.cn/A6ZaBnIr
JVM内存模型和性能调优:http://t.cn/A6wWMVqG