滑动时间窗口限流算法实现

package com.xxxx.seckill.limit;

import java.util.LinkedList;

/**
 * @author WangHeng
 * @version V1.0
 * @date 2023/1/9- 16:15
 * @desc 滑动时间限流算法
 **/
public class AutoTimeLimit {
    //单位时间内请求的总个数
    private Integer reqCount;
    //使用LinkedList记录10个格子
    private LinkedList<Integer> slots = new LinkedList<>();
    //单位时间内最大请求数
    private Integer limitNum = 100;
    //滑动时间窗口中每个格子的时间长度 单位:ms
    private Long windowLength = 100L;
    //滑动时间窗口中的格子数量
    private Integer windowNum = 10;

    //定义构造方法,开辟新的线程,每100ms添加一个新的格子
    // ,如果大于10个的话就移除并更新全局变量的个数。
    public AutoTimeLimit() {
        //初始化的时候add一个0至list当中
        slots.addLast(0);
        new Thread(() -> {
            try {
                //然后每个100ms,在list后面add一个0
                Thread.sleep(windowLength);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            slots.addLast(0);
            //如果list的size一旦大于10,将第一个元素remove掉,使得list的size永远等于10
            if (slots.size() > windowNum) {
                //倘若size大于10的时候,时间肯定是超过了1s中了,
                // 所以第一个元素已经不在统计单位时间内了,应删掉第一个格子的数目,更新全局的个数。
                reqCount = reqCount - slots.peekFirst();
                //移除第一个格子的元素
                slots.removeFirst();
            }
        }).start();
    }

    /**
     * 方法限流方法
     *
     * @return true:代表限流 false:代表通过
     */
    public synchronized Boolean limit() {
        //如果全局变量的个数加上当前访问的个数1大于100的话,直接限流.
        if ((reqCount + 1) > limitNum) {
            return true;
        }
        //slots.size()-1为最后一个格子的下标,使得最后一个格子的数目+1
        slots.set(slots.size() - 1, slots.peekLast() + 1);
        //全局变量更新个数
        reqCount++;
        //表示通过
        return false;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值