4种分布式限流算法

1.计数限流算法实现

bash 复制代码
public class CounterLimiter {

    private Long timeStamp = System.currentTimeMillis();
    //请求次数
    private  int reqCount;
    //每秒限流的最大请求书
    private  int limitNum = 100;
    //时间间隔
    private  Long interval = 1000L;


    /***
     * @Description
     * @Param []
     * @Return java.lang.Boolean 返回true代表限流,false代表通过
     **/
    public synchronized Boolean limit(){
        Long now = System.currentTimeMillis();
        if(now < timeStamp + interval){
            if(reqCount + 1 > limitNum){
                return true;
            }
            reqCount++;
            return false;
        }else{
            timeStamp = now;
            reqCount = 1;
            return false;
        }
    }
}

2.滑动窗口限流算法实现

bash 复制代码
public class SlidingTimeWindowLimiter {

    //请求计数器
    private int reqCount;
    //使用LinkedList来记录滑动窗口的10个格子
    private LinkedList<Integer> slots = new LinkedList<>();
    //每秒限流的最大请求数
    private int limitNum = 100;
    //滑动窗口每个格子的时间长度,单位ms
    private long windowLength = 100;
    //滑动窗口的格子数量
    private int windowNum = 10;

    public synchronized Boolean limit(){
        if(reqCount + 1 > limitNum){
            return true;
        }
        slots.set(slots.size() - 1, slots.peekLast() + 1);
        reqCount++;
        return false;
    }

    public SlidingTimeWindowLimiter() {
        slots.add(0);
        new Thread(() -> {
            while (true) {
                try{
                    TimeUnit.MILLISECONDS.sleep(windowLength);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                synchronized (this) {
                    //滑动窗口
                    slots.add(0);
                    if(slots.size() > windowNum){
                        reqCount -= slots.peekFirst();
                        slots.removeFirst();
                    }
                }
            }
        }).start();
    }
}

3.漏桶限流算法实现

bash 复制代码
public class LeakyBucketLimiter {

    private long timeStamp = System.currentTimeMillis();
    //桶的容量
    private long capacity = 100;
    //水漏的速度(每秒系统能处理的请求数)
    private long rate = 10;
    //当前水量(当前积累请求书)
    private long water = 0;

    public synchronized Boolean limit(){
        long now = System.currentTimeMillis();
        water = Math.max(0, (now - timeStamp)/1000 * rate);
        timeStamp = now;
        if(water + 1 <= capacity){
            water++;
            return false;
        }else {
            //水满,拒绝加水
            return true;
        }


    }
}

4.令牌桶限流算法实现

bash 复制代码
public class TokenBucketLimiter {
    private long timeStamp = System.currentTimeMillis();
    //桶的容量
    private long capacity = 100;
    //水漏的速度(每秒系统能处理的请求数)
    private long rate = 10;
    //当前水量(当前积累请求书)
    private long tokens = 100;


    public synchronized Boolean limit(){
        long now = System.currentTimeMillis();
        //先添加令牌
        tokens = Math.min(capacity, tokens + (now - timeStamp)/1000 * rate);
        timeStamp = now;
        if(tokens - 1 > 0){
            return true;
        }
        //领取令牌
        tokens --;
        return false;
    }
}
相关推荐
暴力求解7 分钟前
C++类和对象(上)
开发语言·c++·算法
让我们一起加油好吗20 分钟前
【基础算法】枚举(普通枚举、二进制枚举)
开发语言·c++·算法·二进制·枚举·位运算
大锦终21 分钟前
【C++】特殊类设计
开发语言·c++
Bruce_Liuxiaowei1 小时前
PHP文件包含漏洞详解:原理、利用与防御
开发语言·网络安全·php·文件包含
泽02021 小时前
C++之STL--list
开发语言·c++·list
YGGP1 小时前
吃透 Golang 基础:数据结构之 Map
开发语言·数据结构·golang
~plus~1 小时前
Harmony核心:动态方法修补与.NET游戏Mod开发
开发语言·jvm·经验分享·后端·程序人生·c#
步、步、为营1 小时前
.NET 事件模式举例介绍
java·开发语言·.net
htj101 小时前
C# 使用正则表达式
正则表达式·c#
~plus~1 小时前
WPF八大法则:告别模态窗口卡顿
开发语言·经验分享·后端·程序人生·c#