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;
    }
}
相关推荐
长河38 分钟前
Java开发者LLM实战——LangChain4j最新版教学知识库实战
java·开发语言
Cyan_RA91 小时前
SpringMVC @RequestMapping的使用演示和细节 详解
java·开发语言·后端·spring·mvc·ssm·springmvc
在未来等你4 小时前
Elasticsearch面试精讲 Day 17:查询性能调优实践
大数据·分布式·elasticsearch·搜索引擎·面试
再见晴天*_*4 小时前
SpringBoot 中单独一个类中运行main方法报错:找不到或无法加载主类
java·开发语言·intellij idea
lqjun08275 小时前
Qt程序单独运行报错问题
开发语言·qt
大数据CLUB7 小时前
基于spark的澳洲光伏发电站选址预测
大数据·hadoop·分布式·数据分析·spark·数据开发
hdsoft_huge7 小时前
Java & Spring Boot常见异常全解析:原因、危害、处理与防范
java·开发语言·spring boot
风中的微尘7 小时前
39.网络流入门
开发语言·网络·c++·算法
未来之窗软件服务8 小时前
幽冥大陆(二)RDIFSDK 接口文档:布草洗涤厂高效运营的技术桥梁C#—东方仙盟
开发语言·c#·rdif·仙盟创梦ide·东方仙盟
小冯记录编程8 小时前
C++指针陷阱:高效背后的致命危险
开发语言·c++·visual studio