每日算法-限流算法
令牌桶算法#
public class TokenBucket {
private final double rate;//生成令牌的速率
private double currentToken;//当前令牌的数量
private final long maxToken;//桶最大容量
private final long lastTime;//上次补充令牌的时间戳
private final ReentrantLock lock=new ReentrantLock();
public TokenBucket(double rate,long maxToken){
this.maxToken=maxToken;
this.rate=rate;
this.lastTime=System.currentTimeMillis();
}
private boolean tryAcquire(){
return tryAcquire(1);
}
private boolean tryAcquire(int need){
lock.lock();
try {
long now=System.currentTimeMillis();
this.currentToken=Math.min((now-lastTime)*this.rate+this.currentToken,this.maxToken);
if (this.currentToken>=need){
return true;
}
return false;
}finally {
lock.unlock();
}
}
}
漏桶算法#
public class LeakyBucket {
private final double leakRate;
private final int capacity;
private double water;
private long lastLeakTime;
private final ReentrantLock lock=new ReentrantLock();
public LeakyBucket(double leakRate,int capacity){
this.capacity=capacity;
this.leakRate=leakRate;
this.lastLeakTime=System.currentTimeMillis();
this.water=0;
}
private boolean tryAcquire(){
lock.lock();
try{
long now =System.currentTimeMillis();
double del=(now-lastLeakTime)*leakRate;
water=Math.max(0,water-del);
lastLeakTime=now;
if (water<capacity){
water++;
return true;
}
return false;
}finally {
lock.unlock();
}
}
}
滑动时间窗口#
public class SlidingWindow {
private final int limit;
private final long windowMs;
private final Queue<Long>queue=new LinkedList<>();
private final ReentrantLock lock=new ReentrantLock();
public SlidingWindow(int limit,int windowMs){
this.limit=limit;
this.windowMs=windowMs;
}
private boolean tryAcquire(){
lock.lock();
try{
long now=System.currentTimeMillis();
long expireTime=now-windowMs;
while (!queue.isEmpty() && queue.peek() < expireTime) {
queue.poll();
}
if (queue.size() < limit) {
queue.offer(now);
return true;
}
return false;
}
finally {
lock.unlock();
}
}
}
三种算法的对比#
令牌算法#
平时没有人使用的时候会积攒满令牌,所以可以抗一波突击流量
漏桶算法#
水流出的速度的固定的,处理请求的速度是固定的。流量均匀,保护脆弱下游
滑动窗口#
qps精准统计,但是在临界值方面容易出现问题
原创
algorithm-005
本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
评论交流
欢迎留下你的想法