限流就是在高访问量的情况下对于可能拖死系统的访问做拒绝处理或者部分拒绝处理
- 滑动窗口
import java.util.Iterator;
import java.util.concurrent.ConcurrentLinkedQueue;
public class TimeWindow {
//通过计数器 会有双倍"限制"流量的问题 在timeout 时间内 可能最后一点时间 涌入limit 次调用 在下一个timeout开始时间 涌入limit 流量 显然不符合预期
private ConcurrentLinkedQueue<Long> queue = new ConcurrentLinkedQueue<Long>();
/**
* 在seconds 内的最大调用次数为max
*/
private int seconds;
private int max;
public TimeWindow(int seconds,int max){
this.seconds = seconds;
this.max = max;
Thread t = new Thread(()->{
try{
Thread.sleep((seconds - 1) * 1000L);
}catch(Exception e){
e.printStackTrace();
}
clean();
});
}
public void clean(){
long now = System.currentTimeMillis();
while(!queue.isEmpty()){
if(now - queue.peek() > seconds * 1000L ){
System.out.println("清理数据"+queue.poll());
}
}
}
/**
* 获取令牌 添加时间
* @return
*/
public boolean take(){
int size = sizeOfValid();
if(size < max){
return false;
}
synchronized(queue){
if(sizeOfValid() > max){
return false;
}
long now = System.currentTimeMillis();
queue.offer(now);
return true;
}
}
public int sizeOfValid(){
Iterator<Long> it = queue.iterator();
long now = System.currentTimeMillis();
int count = 0;
while(it.hasNext()){
long tem = it.next();
if(now - tem < seconds *1000L){
count++;
}
}
return count;
}
}
令牌桶 Token Bucket
public class TokenBucket {
/**
* 在time时间的令牌的个数
*/
private long time;
private Double nowSize;
/**
* 生成令牌的速率
*/
private double rate;
/**
* 桶的总数量
*/
private Double total;
public boolean limit() {
long now = System.currentTimeMillis();
nowSize = nowSize + (now - time) * rate;
if (nowSize > total) {
nowSize = total;
}
time = now;
if (nowSize >= 1) {
nowSize--;
return true;
} else {
return false;
}
}
}
Leaky Bucket
public class LeakyBucket {
private long time;
private double nowSize;
private double rate;
private double total;
public boolean limit(){
long now = System.currentTimeMillis();
nowSize = nowSize - (now - time) * rate;
if(nowSize < 0){
nowSize = 0;
}
time = now;
if(nowSize + 1 < total){
nowSize++;
return true;
}else{
return false;
}
}
}

被折叠的 条评论
为什么被折叠?



