返回
大揭秘!揭秘限流算法背后的秘密
后端
2023-10-14 07:04:58
在开发过程中,我们经常会遇到高并发场景,或者面临一些恶意请求。为了保护我们的系统,保持系统的稳定性,我们需要对请求进行限流。限流算法是一种有效的流量控制机制,它可以限制系统在单位时间内处理请求的数量,防止系统过载。
计数法
计数法是最简单的一种限流算法。它的原理非常简单,就是记录一段时间内请求的数量,当请求数量达到某个阈值时,就拒绝新的请求。
计数法的实现也非常简单,我们可以使用一个变量来记录一段时间内请求的数量。当新的请求到来时,我们就将变量加一。当变量达到阈值时,我们就拒绝新的请求。
public class CounterLimiter {
private int limit;
private int count;
public CounterLimiter(int limit) {
this.limit = limit;
this.count = 0;
}
public boolean allow() {
if (count < limit) {
count++;
return true;
} else {
return false;
}
}
}
令牌桶
令牌桶算法也是一种常用的限流算法。它的原理是,系统会生成一个令牌桶,桶中包含一定数量的令牌。当新的请求到来时,系统会从桶中取出一个令牌。如果没有令牌,则拒绝新的请求。
令牌桶算法的实现也比较简单,我们可以使用一个队列来模拟令牌桶。当系统生成一个令牌时,我们就将令牌添加到队列中。当新的请求到来时,我们就从队列中取出一个令牌。如果没有令牌,则拒绝新的请求。
public class TokenBucketLimiter {
private int capacity;
private Queue<Long> tokens;
private long lastTimestamp;
public TokenBucketLimiter(int capacity) {
this.capacity = capacity;
this.tokens = new LinkedList<>();
this.lastTimestamp = System.currentTimeMillis();
}
public boolean allow() {
long now = System.currentTimeMillis();
long elapsedTime = now - lastTimestamp;
lastTimestamp = now;
// 生成令牌
long tokensToAdd = elapsedTime / 1000;
while (tokensToAdd > 0) {
tokens.add(now);
tokensToAdd--;
}
// 取出令牌
if (!tokens.isEmpty()) {
tokens.remove();
return true;
} else {
return false;
}
}
}
总结
计数法和令牌桶算法都是常用的限流算法。计数法简单易实现,但它对突发流量不友好。令牌桶算法可以应对突发流量,但它的实现相对复杂。
在实际应用中,我们可以根据业务场景选择合适的限流算法。如果业务场景对突发流量不敏感,则可以使用计数法。如果业务场景对突发流量敏感,则可以使用令牌桶算法。