漏桶算法比较形象,设想有一个桶,桶的底部有一个洞,当装上水的时候,水会一滴一滴地从底部漏掉。当装的水太满,水会溢出,但底部漏水的速度还是不变的。
底部漏水的速度就是系统处理的速度,桶里存储的水就是上游过来的请求。当请求太多,超过桶的容量,就会被拒绝。系统只在另一端按照固有的速度处理请求。
如下图所示,外部的请求随机而来,把“桶”填满后,装不进“桶”的请求被丢弃。每秒从“桶”中匀速“漏出”一定量的“水”(请求),服务进程处理漏出的请求包。
当请求突增的时候,漏桶算法能够保证处理速度总是恒定的。
在系统启动时,如果想让系统有一个陆续启动的过程,则不用一下子接受太多请求,让系统处理请求量平缓上升到最大处理能力。
系统可以在一些时刻处理突增的请求,只要持续时间不是很长,系统有能力处理即可。
1 桶的容量是承载2000个请求,处理速度是每毫秒1个请求。即1秒1000个请求。
2 外部最大请求为 1500 个,并随机取值,会限流吗?
package currentLimit;
import java.util.Random;
/**
* @className: LeakBucket
* @description: 漏桶算法
* @date: 2022/1/8
* @author: cakin
*/
public class LeakBucket {
static long cur = 0; // 当前桶中累计的请求数
// 记录上次统计时间的毫秒
static long lastTime = System.currentTimeMillis();
/**
* 功能描述:漏桶算法
*
* @param capcity 桶能承载的最大请求数,超过这个数就开始限流
* @param rate 为漏水的速度,系统每秒能处理的请求
* @return true:限流 false:不限流
* @author cakin
* @date 2022/1/9
*/
static boolean leakBuck(int capcity, int rate) {
// 当前毫秒
long millisTime = System.currentTimeMillis();
// 两次请求的间隔,单位是毫秒
long time = (millisTime - lastTime);
cur = Math.max(0, cur - time * rate);
lastTime = millisTime;
++cur;
if (cur >= capcity) {
cur = capcity;
return true;
}
return false;
}
// 测试方法
public static void main(String[] args) {
for (; ; ) {
// 停顿1秒
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 模拟1秒请求的次数 1500次内
int randomTime = new Random().nextInt(1500); // 通过调这个值,来测试是否限流
for (int j = 0; j < randomTime; j++) {
if (leakBuck(2000, 1)) {
System.out.println("限流了" + cur);
} else {
System.out.println("没限流" + cur);
}
}
}
}
}
从测试来看,当外部请求的的请求数在1500内随机取值,还是可能限流的。
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/chengqiuming/article/details/122396182
内容来源于网络,如有侵权,请联系作者删除!