返回

大揭秘!揭秘限流算法背后的秘密

后端

在开发过程中,我们经常会遇到高并发场景,或者面临一些恶意请求。为了保护我们的系统,保持系统的稳定性,我们需要对请求进行限流。限流算法是一种有效的流量控制机制,它可以限制系统在单位时间内处理请求的数量,防止系统过载。

计数法

计数法是最简单的一种限流算法。它的原理非常简单,就是记录一段时间内请求的数量,当请求数量达到某个阈值时,就拒绝新的请求。

计数法的实现也非常简单,我们可以使用一个变量来记录一段时间内请求的数量。当新的请求到来时,我们就将变量加一。当变量达到阈值时,我们就拒绝新的请求。

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;
        }
    }
}

总结

计数法和令牌桶算法都是常用的限流算法。计数法简单易实现,但它对突发流量不友好。令牌桶算法可以应对突发流量,但它的实现相对复杂。

在实际应用中,我们可以根据业务场景选择合适的限流算法。如果业务场景对突发流量不敏感,则可以使用计数法。如果业务场景对突发流量敏感,则可以使用令牌桶算法。