滑动窗口限流算法实现一

news2024/9/25 13:16:14

固定算法

原理:固定算法是将时间线分隔成固定大小的时间窗口,每个窗口都会有个计数器,用来记录窗口时间范围内的请求总数,如果窗口的请求总数达到最大限定值,会认定流量超限。比如将窗口大小设为1分钟,每分钟请求最大数为2:
在这里插入图片描述
请求在00:00:24时刻到来的时候,会落在窗口1内,计数器值为1,下一个请求在00:00:36时刻,也会落在窗口1内,计数器值+1变成,第三个请求在00:00:49时刻来到,此时计数器值已达到最大限定值2,请求会被拒掉,最后一个请求在00:01:12到来,会落在窗口2内。

固定算法的缺点

固定算法只能判断单个窗口内的请求总数,但是无法判断相邻的两个窗口,落在相邻窗口的两个请求时间间隔完全有可能在一个窗口时间范围内。比如00:00:58和00:00:59两个时刻各有一个请求过来,窗口1的计数器值为2, 第三个请求在00:01:01到来,会落在窗口2内,但是00:00:58和00:01:01之间没有超过一个单元时间1分钟,但是请求总数已经超过最大限定值2。

滑动窗口算法

为了优化固定算法的缺点,将固定大小的时间窗口分成更小的时间窗口,比如1min的窗口分成6个10s的小窗口。

实现一(简单无脑版)

思路:

1.   使用一个Map:counterMap 用来存储每个时间戳的请求总数
2.   请求到来时,会将单位时间之前(now-timeUnit)的所有请求记录全部清除
3.   统计单位时间timeUnit内的请求总数
4.   判断请求总数是否超过请求阈值capacity,超过则返回false
5.   没有超过,则记录当前时间戳和请求。

源码:

public class SlidingWindow3 {
    /**
     * 单位时间请求阈值
     */
    private int capacity;
    /**
     * 单位时间/ms
     */
    private long timeUnit;

    /**
     * 时间戳计数器
     */
    private Map<Long,Integer> counterMap = new HashMap<>();

    public SlidingWindow3(int capacity, long timeUnit) {
        this.capacity = capacity;
        this.timeUnit = timeUnit;
    }

    public synchronized boolean tryAcquire() {
        long now = System.currentTimeMillis();
        long start = now-timeUnit;
        Iterator<Map.Entry<Long, Integer>> iterator = counterMap.entrySet().iterator();
        while (iterator.hasNext()){
            if(iterator.next().getKey()<start){
                iterator.remove();
            }
        }
        iterator = counterMap.entrySet().iterator();
        int totalCount = 0;

        while (iterator.hasNext()){
            totalCount += iterator.next().getValue();
        }

        if(totalCount>= capacity){
            return false;
        }
        if(counterMap.containsKey(now)){
            counterMap.put(now,counterMap.get(now)+1);
        }else {
            counterMap.put(now,1);
        }
        return true;
    }
}

测试

 public static void main(String[] args) throws InterruptedException {
        SlidingWindow3 slidingWindow = new SlidingWindow3(2, 1000);
        for (int j = 0; j < 10; j++) {
            System.out.println("第:" + j + "轮测试");
            int concurrency = 30;
            CyclicBarrier cyclicBarrier = new CyclicBarrier(concurrency);
            for (int i = 1; i <= concurrency; i++) {
                new Thread("Thread:" + i) {
                    @Override
                    public void run() {
                        try {
                            cyclicBarrier.await();
                            if (slidingWindow.tryAcquire()) {
                                System.out.println("name:" + Thread.currentThread().getName() + " get permit");
                            }
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        } catch (BrokenBarrierException e) {
                            e.printStackTrace();
                        }
                    }
                }.start();
            }
            Thread.sleep(3 * 1000L);
        }
    }

结果

在这里插入图片描述

参考

《Rate-Limiter-Part1》

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1151849.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

怎么搭建一个蛋糕店小程序?

在当今的移动互联网时代&#xff0c;很多企业纷纷选择了小程序作为推广和销售的利器。对于蛋糕店来说&#xff0c;创建一个小程序可以提高品牌知名度&#xff0c;增加销售渠道。下面&#xff0c;我们以【乔拓云】第三方平台为例&#xff0c;来介绍一个完整蛋糕店小程序的制作流…

Java学习 5.Java-逻辑控制

逻辑控制 逻辑控制分为&#xff1a;选择语句、循环语句 一、if和switch选择语句 顺序中夹杂着循环&#xff0c;伴随着一次次的选择不断地成长 1.if语句 选择语句 单分支 if() 表达式; int a60;if(a60){System.out.println("a60");} 双分支 if(){ 表达式1&…

人工智能AI 全栈体系(九)

第一章 神经网络是如何实现的 如何用神经网络处理不等长文本的方法&#xff1f; 八、循环神经网络&#xff08;RNN: Recurrent Neural Network&#xff09; 处理不等长文本的神经网络 – 循环神经网络 RNN。 1. 从句子理解说起 上次讲了用词向量表示词&#xff0c;一句话也…

Vue Router:让你的应用路由起来!

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

uni-app:查询对象中字段为可变情况的子项

如上图&#xff0c;数据中aaa为可变项&#xff0c;需要查询其子项name的值 var test aaa var data {"no":1,"aaa": {"name":张三,"age": 20}, } console.log(data[test].name) 定义一个变量test&#xff0c;其值设置为aaa&#xff…

SENet: 强化深度卷积神经网络的自适应特征学习

SENet&#xff08;Squeeze-and-Excitation Network&#xff09;是一种革命性的深度卷积神经网络架构&#xff0c;旨在提高模型对图像特征的建模能力。它引入了自适应特征重新校准机制&#xff0c;通过学习性地调整通道间的重要性&#xff0c;提高了模型的性能&#xff0c;广泛用…

在Windows上 ciphey安装(详细版)

文章目录 前言 一、不想卸载原有的python版本&#xff1f; 二、安装步骤 1.安装python 2.创建虚拟环境vnev 3.在ciphey的虚拟环境中进行激活 4.安装ciphey 三、参数列表 总结 前言 提示&#xff1a;安装了好几次&#xff0c;但是都没安装成功&#xff0c;我使用了三个电脑p…

前后端分离问题 | 协调

CORS error 跨域问题--->找后端 报错&#xff1a;Access to XMLHttpRequest at http://xxx/Info?id5 from origin http://localhost:xxx has been blocked by CORS policy: No Access-Control-Allow-Origin header is present on the requested resource.

阿里DDD大佬:从0到1,带大家精通DDD

说在前面 在40岁老架构师 尼恩的读者交流群(50)中&#xff0c;最近有小伙伴拿到了一线互联网企业如阿里、滴滴、极兔、有赞、希音、百度、网易、美团的面试资格&#xff0c;遇到很多很重要的面试题&#xff1a; 谈谈你的DDD落地经验&#xff1f; 谈谈你对DDD的理解&#xff1…

【word小技巧】如何在方框中打√

1、新建一个word文档 2、点击“插入”–>“符号”–>“其他符号” 3、字体选择“wingdings 2”&#xff0c;然后就可以看到想要的符号了。选择之后&#xff0c;点击插入 4、完成插入

堆叠大陆Stacklands中文版:激发你的创意与策略,开启全新的建造体验

你是否曾经梦想过成为一个建筑师&#xff0c;创造自己的世界&#xff1f;或者向往那些无尽的策略游戏&#xff0c;在其中规划、建造并统治一切&#xff1f;现在&#xff0c;这个梦想已经触手可及&#xff0c;因为堆叠大陆Stacklands正等待你的探索&#xff01; 堆叠大陆Stackl…

【多线程面试题十六】、谈谈ReentrantLock的实现原理

文章底部有个人公众号&#xff1a;热爱技术的小郑。主要分享开发知识、学习资料、毕业设计指导等。有兴趣的可以关注一下。为何分享&#xff1f; 踩过的坑没必要让别人在再踩&#xff0c;自己复盘也能加深记忆。利己利人、所谓双赢。 面试官&#xff1a;谈谈ReentrantLock的实现…

pytorch:R-CNN的pytorch实现

pytorch&#xff1a;R-CNN的pytorch实现 仅作为学习记录&#xff0c;请谨慎参考&#xff0c;如果错误请评论指出。 参考文献&#xff1a;Rich Feature Hierarchies for Accurate Object Detection and Semantic Segmentation      https://blog.csdn.net/qq_41694024/cat…

S5PV210裸机(九):ADC

本文主要探讨210的ADC相关知识。 ADC ADC:模数转换&#xff08;模拟信号转数字信号&#xff09; 量程:模拟电压信号范围(210为0&#xff5e;3.3V) 精度:若10二进制位来表示精度&#xff08;210为10位或12位&#xff09;,量…

Umijs项目优化

首先通过npm run analyze 查看打包后的文件进行观察&#xff0c;哪些包的体积大&#xff0c;然后分解开 体积较大的文件:echarts、wangeditor、antd、moment.js package.json 文件配置 .umirc.ts配置文件 1. 分包配置 通过 webpack-chain 的 API 修改 webpack 配置。 chunk…

水果音乐编辑软件 flstudio_mac_21.2.0.3405中文破解版

flstudio_mac_21.2.0.3405中文破解版是Mac系统中的一款水果音乐编辑软件&#xff0c;提供多种插件&#xff0c;包括采样器、合成器和效果器&#xff0c;可编辑不同风格的音乐作品&#xff0c;Pattern/Song双模式&#xff0c;可兼容第三方插件和音效包&#xff0c;为您的创意插上…

.jnlp打开方式

首先配置电脑的java环境。 百度搜索jre下载&#xff0c;会有很多结果&#xff0c;一般选择官网进行下载。 下载正确的jre版本。 我的电脑是windows 64位&#xff0c;根据你自己电脑的情况选择版本进行下载。不懂自己电脑是多少位的可以看下一步。 查看电脑是64位还是32…

halcon roberts、 prewitt_amp、 sobel_amp、 edges_image、 laplace_of_gauss 对比

原图 灰度&#xff1a; roberts 算子&#xff1a; prewitt算子 sobel 算子 canny算子 拉普拉斯 代码&#xff1a; read_image (Image, C:/Users/alber/Desktop/opencv_images/canny.png) rgb1_to_gray (Image, GrayImage)* 测试 roberts 算子 roberts (GrayImage, ImageRoberts…

使用自动编码器进行半监督异常检测

使用自动编码器进行半监督异常检测 前言前提条件相关介绍Semi-supervised Anomaly Detection using AutoEncoders项目结构训练模型测试模型 参考 前言 由于本人水平有限&#xff0c;难免出现错漏&#xff0c;敬请批评改正。更多精彩内容&#xff0c;可点击进入YOLO系列专栏、自…

【NI-DAQmx入门】数字IO基础知识

1.漏端和源端数字IO的区别 漏端和源端是用于定义负载中直流电流控制的术语&#xff0c;分别表示所用到的数字输入和输出的类型。 漏端的数字I / O&#xff08;输入/输出&#xff09;提供与负载的接地连接。源端的数字I / O为负载提供电压源。 以一个由数字输入与数字输出相连…