常用限流算法介绍

限流是防止系统过载的重要手段,广泛应用于高并发场景。


1. 什么是限流算法?

定义

限流算法是一种用于控制请求流量的技术,防止系统因请求过多而过载。通过限制单位时间内允许通过的请求数量,可以有效保护系统资源,确保服务的稳定性和可用性。


2. 常见的限流算法

2.1 固定窗口计数器算法

原理:将时间分成固定大小的窗口,每个窗口内允许通过的请求数量固定。如果当前窗口的请求数量超过限制,则拒绝后续请求。

优点

  • 实现简单,性能高。

缺点

  • 在窗口切换时可能出现突发流量,导致限流不准确。

实际应用场景

  • 网关服务:限制每个用户的请求频率。

  • 数据库访问:限制每秒的查询次数。

示例代码

import java.util.concurrent.atomic.AtomicInteger;

public class FixedWindowRateLimiter {
    private final int limit;
    private final AtomicInteger counter = new AtomicInteger(0);
    private long startTime = System.currentTimeMillis();

    public FixedWindowRateLimiter(int limit) {
        this.limit = limit;
    }

    public synchronized boolean allowRequest() {
        long now = System.currentTimeMillis();
        if (now - startTime >= 1000) { // 1秒窗口
            counter.set(0);
            startTime = now;
        }
        return counter.incrementAndGet() <= limit;
    }
}

2.2 滑动窗口日志算法

原理:记录每个请求的时间戳,通过滑动窗口的方式计算单位时间内的请求数量。如果请求数量超过限制,则拒绝后续请求。

优点

  • 精确控制流量,避免突发流量问题。

缺点

  • 实现相对复杂,需要存储请求的时间戳。

实际应用场景

  • API网关:限制每个用户的调用频率。

  • 微服务:限制每个服务的调用频率。

示例代码

import java.util.LinkedList;
import java.util.Queue;

public class SlidingWindowLogRateLimiter {
    private final int limit;
    private final Queue<Long> timestamps = new LinkedList<>();
    private final long windowSize = 1000; // 1秒窗口

    public SlidingWindowLogRateLimiter(int limit) {
        this.limit = limit;
    }

    public synchronized boolean allowRequest() {
        long now = System.currentTimeMillis();
        while (!timestamps.isEmpty() && timestamps.peek() <= now - windowSize) {
            timestamps.poll();
        }
        if (timestamps.size() < limit) {
            timestamps.add(now);
            return true;
        }
        return false;
    }
}

2.3 漏桶算法

原理:通过一个漏桶来控制流量,漏桶以固定速率漏水,请求进入漏桶后按顺序流出。如果漏桶满了,则拒绝后续请求。

优点

  • 平滑流量,避免突发流量。

缺点

  • 实现相对复杂,需要维护一个队列。

实际应用场景

  • 网络流量控制:平滑网络流量。

  • 任务调度:控制任务的执行速率。

示例代码

import java.util.LinkedList;
import java.util.Queue;

public class LeakyBucketRateLimiter {
    private final int capacity;
    private final long leakRate;
    private final Queue<Long> timestamps = new LinkedList<>();
    private long lastLeakTime = System.currentTimeMillis();

    public LeakyBucketRateLimiter(int capacity, long leakRate) {
        this.capacity = capacity;
        this.leakRate = leakRate; // 每秒漏水速率
    }

    public synchronized boolean allowRequest() {
        long now = System.currentTimeMillis();
        long elapsed = now - lastLeakTime;
        lastLeakTime = now;

        // 漏水
        int leaked = (int) (elapsed * leakRate / 1000);
        while (!timestamps.isEmpty() && leaked > 0) {
            timestamps.poll();
            leaked--;
        }

        if (timestamps.size() < capacity) {
            timestamps.add(now);
            return true;
        }
        return false;
    }
}

2.4 令牌桶算法

原理:通过一个令牌桶来控制流量,令牌桶以固定速率生成令牌,请求需要消耗一个令牌才能通过。如果令牌桶为空,则拒绝后续请求。

优点

  • 精确控制流量,支持突发流量。

缺点

  • 实现相对复杂,需要维护令牌桶。

实际应用场景

  • API网关:限制每个用户的调用频率。

  • 微服务:限制每个服务的调用频率。

示例代码

import java.util.concurrent.atomic.AtomicLong;

public class TokenBucketRateLimiter {
    private final long rate;
    private final long capacity;
    private final AtomicLong tokens = new AtomicLong(0);
    private long lastRefillTime = System.currentTimeMillis();

    public TokenBucketRateLimiter(long rate, long capacity) {
        this.rate = rate; // 每秒生成的令牌数
        this.capacity = capacity;
        this.tokens.set(capacity);
    }

    public synchronized boolean allowRequest() {
        long now = System.currentTimeMillis();
        long elapsed = now - lastRefillTime;
        lastRefillTime = now;

        // 填充令牌
        long newTokens = elapsed * rate / 1000;
        long currentTokens = Math.min(tokens.get() + newTokens, capacity);
        tokens.set(currentTokens);

        if (tokens.get() > 0) {
            tokens.decrementAndGet();
            return true;
        }
        return false;
    }
}

3. 推荐书籍

3.1 《高性能架构设计》

  • 作者:[Richardson, Sam]

  • 内容简介:这本书详细介绍了高性能架构的设计原则和实践,包括限流、缓存、负载均衡等技术。

  • 适用人群:系统架构师、高级开发工程师。

3.2 《分布式系统:概念与设计》

  • 作者:[George Coulouris, Jean Dollimore, Tim Kindberg]

  • 内容简介:这本书涵盖了分布式系统的基础知识,包括限流、一致性、容错等重要概念。

  • 适用人群:分布式系统开发者、系统架构师。

3.3 《高并发编程实战》

  • 作者:[张开涛]

  • 内容简介:这本书结合实际案例,详细介绍了高并发编程的技巧和方法,包括限流、线程池、锁等技术。

  • 适用人群:Java开发工程师、系统架构师。


4. 总结

  • 固定窗口计数器算法:简单高效,但可能出现突发流量问题。

  • 滑动窗口日志算法:精确控制流量,避免突发流量问题。

  • 漏桶算法:平滑流量,避免突发流量。

  • 令牌桶算法:精确控制流量,支持突发流量。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

十五001

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值