限流算法 计数器 滑动时间窗口 漏桶 令牌桶

计数器法

public class Counter {

    private long timestamp = System.currentTimeMillis(); //当前时间窗口起始时间

    private int reqCount = 0;  //当前时间窗口计数器(请求数)

    private final int reqLimitCount = 100; //限流阈值

    private final long intervalMs = 1000; //时间窗口 ms

    //返回false限流,true不限流
    public boolean limit() {
        long now = System.currentTimeMillis();
        if (now < timestamp + intervalMs) { //在当前时间窗口
            reqCount++; //递增请求数
            return reqCount < reqLimitCount; //判断请求数是否小于阈值
        } else {  //不在当前时间窗口
            timestamp = now; //重置当前时间窗口起始时间
            reqCount = 1; //重置当前时间窗口内请求数
            return true;
        }
    }
}

滑动时间窗口

* 示例:
* 模拟1s限制100个请求
* 
* 滑动时间窗口将1s划分10个格子,每个格子100ms,每100ms滑动时间窗口向右滑动一次(增加一个格子,移除第一个格子),每个格子计数器记录了到此刻的总请求数
* 例如这个滑动时间窗口[10,20,30,40,50,60,70,80,90,100] ,截止到第一个格子的时间请求数10,截止到第10个格子的时间请求数100,1s时间窗口累计请求数为100-10=90个请求  
public class SlideTimeWindow {
    private volatile long reqCount=0; //当前累计请求数,可存储在redis中,实现分布式集群请求次数统计
    private long reqLimitCount = 100; //限流阈值
    private volatile boolean pass=true; //是否允许请求通过,true 允许通过,false 不允许通过
    public static void main(String[] args) throws InterruptedException {
        SlideTimeWindow slideTimeWindow = new SlideTimeWindow();
        //启动滑动时间窗口限流
        new Thread(()->{
            try {
                slideTimeWindow.limit();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }).start();
        //模拟应用请求不断的到来
        while (true){ //模拟在未被限流时,随机10ms内,就会来一个请求
            if(slideTimeWindow.pass){
                slideTimeWindow.reqCount=slideTimeWindow.reqCount+1;
            }
            TimeUnit.MILLISECONDS.sleep((long) (Math.random() * 10));
        }
    }
    public void limit() throws InterruptedException {
        LinkedList<Long> slots = new LinkedList<>(); //滑动时间窗口,假设滑动时间窗口划分了10个格子,格子存储的是截止到当前窗格累计的请求数
        while (true) {
            slots.add(reqCount); 
            if (slots.size() > 10) { //滑动时间窗口超过10个格子,向后滑动一个格子 
                slots.removeFirst();
            }
            if (slots.peekLast() - slots.peekFirst() > reqLimitCount) { //获取滑动时间窗口内累计请求数,并与限流阈值比较,决定是否限流
                System.out.println("被限流了 "+slots);
                pass = false; 
            } else {
                System.out.println("未限流 "+slots);
                pass = true;
            }
            TimeUnit.MILLISECONDS.sleep(100);
        }

    }

}

漏桶

public class LeakyBucket {
    private long capacity; //漏桶容量(限流阈值)
    private long rate; //每秒流出速率(每秒流出的请求数量)
    private long water; //漏桶中当前水量 (当前的请求数)
    private long timestamp=System.currentTimeMillis(); //上次加水时间(请求时间)    

    //是否允许请求通过 true 通过,false 拒绝
    public boolean pass(){
        long now=System.currentTimeMillis();
        //执行漏水,更新当前水量
        water= Math.max(0,water-(now-timestamp)/1000*rate);    
        timestamp=now;
        if(water+1<capacity){
            water++;
            System.out.println("加水成功"); //不需要限流
            return true;
        }else{
            System.out.println("漏桶满了 加水失败"); //需要限流
            return false;
        }
        
    }
    
}

令牌桶

public class TokenBucket {
    private long capacity; //令牌桶容量
    private long rate; //颁发令牌的速率(秒)
    private long tokens; //令牌桶中当前令牌数量
    private long timestamp = System.currentTimeMillis(); //上次颁发令牌时间

    //是否允许请求通过 true 通过,false 拒绝
    public boolean pass() {
        long now = System.currentTimeMillis();
        //颁发令牌,更新桶中当前令牌数量
        tokens = Math.min(capacity, tokens + (now - timestamp) / 1000 * rate);
        timestamp = now;
        if (tokens < 1) { //没有令牌,请求拒绝
            return false;
        } else { //还有令牌,消耗一个令牌,请求通行
            tokens--;
            return true;
        }
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

初始 ShellJS:一个 Node.js 命令行工具集合

一. 前言 Node.js 丰富的生态能赋予我们更强的能力&#xff0c;对于前端工程师来说&#xff0c;使用 Node.js 来编写复杂的 npm script 具有明显的 2 个优势&#xff1a;首先&#xff0c;编写简单的工具脚本对前端工程师来说额外的学习成本很低甚至可以忽略不计&#xff0c;其…

(echarts)数据地图散点类型根据条件设置不同的标记图片

(echarts)数据地图散点类型根据条件设置不同的标记图片 1.用在线工具将本地图片转化base64格式 data(){return { base64Img:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADQ...",} }在线转换地址&#xff1a;https://www.jyshare.com/front-end/59/ 2.symbol属…

Linux高级--2.4.5 靠协议头保证传输的 MAC/IP/TCP/UDP---协议帧格式

任何网络协议&#xff0c;都必须要用包头里面设置写特殊字段来标识自己&#xff0c;传输越复杂&#xff0c;越稳定&#xff0c;越高性能的协议&#xff0c;包头越复杂。我们理解这些包头中每个字段的作用要站在它们解决什么问题的角度来理解。因为没人愿意让包头那么复杂。 本…

网络下载ts流媒体

网络下载ts流媒体 查看下载排序合并 很多视频网站&#xff0c;尤其是微信小程序中的长视频无法获取到准确视频地址&#xff0c;只能抓取到.ts片段地址&#xff0c;下载后发现基本都是5~8秒时长。 例如&#xff1a; 我们需要将以上地址片段全部下载后排序后再合成新的长视频。 …

小程序租赁系统开发指南与实现策略

内容概要 在如今这个快节奏的时代&#xff0c;小程序租赁系统的开发正逐渐成为许多商家提升服务质量与效率的重要选择。在设计这样一个系统时&#xff0c;首先要明白它的核心目标&#xff1a;便捷、安全。用户希望在最短的时间内找到需要的物品&#xff0c;而商家则希望通过这…

机器人C++开源库The Robotics Library (RL)使用手册(一)

强大的、完整的C机器人开源库 1、是否可以免费商用&#xff1f;2、支持什么平台&#xff1f;3、下载地址4、开始&#xff01; 1、是否可以免费商用&#xff1f; Robotics Library&#xff08;RL&#xff09;是一个独立的C库&#xff0c;用于机器人运动学、运动规划和控制。它涵…

Android unitTest 单元测试用例编写(初始)

文章目录 了解测试相关库导入依赖库新建测试文件示例执行查看结果网页结果其他 本片讲解的重点是unitTest&#xff0c;而不是androidTest哦 了解测试相关库 androidx.compose.ui:ui-test-junit4: 用于Compose UI的JUnit 4测试库。 它提供了测试Compose UI组件的工具和API。 and…

Ngnix介绍、安装、实战及用法!!!

一、Nginx简介 1、Nginx概述 Nginx (“engine x”) 是一个高性能的 HTTP 和 反向代理服务器&#xff0c;特点是占有内存少&#xff0c;并发能力强&#xff0c;能经受高负载的考验,有报告表明能支持高达 50,000 个并发连接数 。 2、正向代理 正向代理&#xff1a;如果把局…

国内智能编程助手简易对比:文心一言、通义千问、智谱AI、讯飞星火、Kimi

最近想给IDE选择一个智能编程助手插件&#xff0c;但鉴于国内百花齐放的现状&#xff0c;一时也不好选择用哪个。挑了几个主流的的平台&#xff0c;分别输入“用python实现雪花纷飞的场景”的简单需求&#xff0c;看看效果对比。备注&#xff1a;因国外插件使用成本远高于国内的…

vscode python pip : 无法将“pip”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。()

问题&#xff1a; PS C:\Users\EDY\Desktop\vscodeTest> pip pip : 无法将“pip”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写&#xff0c;如果包括路径&#xff0c;请确保 路径正确&#xff0c;然后再试一次。 所在位置 行:1 字符: 1 pip …

vue3封装而成的APP ,在版本更新后,页面显示空白

一、问题展示 更新之后页面空白&#xff0c;打不开 &#xff0c;主要是由于缓存造成的 二、解决办法 1、随机数代码实现 使用随机数来动态的生成静态资源目录名可以避免浏览器缓存&#xff0c;但同时每次也会导致浏览器每次都下载最新的资源。如果静态资源过大&#xff0c;可…

HarmonyOS NEXT 实战之元服务:静态多案例效果(一)

背景&#xff1a; 前几篇学习了元服务&#xff0c;后面几期就让我们开发简单的元服务吧&#xff0c;里面丰富的内容大家自己加&#xff0c;本期案例 仅供参考 先上本期效果图 &#xff0c;里面图片自行替换 效果图1代码案例如下&#xff1a; import { authentication } from…

SpringAI人工智能开发框架006---SpringAI多模态接口_编程测试springai多模态接口支持

可以看到springai对多模态的支持. 同样去创建一个项目 也是跟之前的项目一样,修改版本1.0.0 这里 然后修改仓库地址,为springai的地址 然后开始写代码

基础运维学习计划-base版

目录 需要学习的内容&#xff1f; liunx基础 sql/mysql基础 tcp/ip协议基础 http基础 dns基础 网络基础&#xff1a;交换&路由概念&原理 常见网络协议 月学习计划 12.26 日 &#xff08;bilibili自己找视频看看&#xff0c;资源很多&#xff09; 12.27日 1…

2、C#基于.net framework的应用开发实战编程 - 设计(二、三) - 编程手把手系列文章...

二、设计&#xff1b; 二&#xff0e;三、构建数据库&#xff1b; 此例子使用的是SQLite数据库&#xff0c;所以数据库工具用的SQLiteStudio x64&#xff0c;这个是SQLite专用的数据库设计管理工具&#xff0c;其它的数据库管理工具比如DBeaver的使用请见实战工具系列文章。 1、…

shardingsphere分库分表项目实践1-让shardingsphere运行起来

学习新技术最快的方式就是&#xff1a; 1. 先找一个比较完善的demo跑起来 2. 弄清楚用法&#xff1a;配置、原理、使用场景 3. 移植到自己项目上&#xff0c;按照自己需求进行修改优化。 找demo项目的方法&#xff1a;优先去官方git库找&#xff0c;如果没有或者过于简单那么…

【运维笔记】windows 11 中提示:无法成功完成操作,因为文件包含病毒或潜在的垃圾软件。

项目场景&#xff1a; 提示&#xff1a;向日葵远程给客户安装数据库管理软件Navicat 15&#xff0c;提示文件被清理&#xff1a; 原因分析&#xff1a; 提示&#xff1a;可能是文件含有病毒&#xff0c;或者是Windows认为我们下载的软件有病毒&#xff0c;还有就是开发过程做…

使用开源在线聊天工具Fiora轻松搭建个性化聊天平台在线交流

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家&#xff1a;人工智能教程 文章目录 前言1.关于Fiora2.安装Docker3.本地部署Fiora4.使用Fiora5.cpolar内网穿透工具安装6.创建远程连接公网地址7.固定Uptime …

【C#联合halcon实现绘制ROI功能】

前言 C#联合halcon实现绘制ROI功能&#xff1a; C#联合Halcon&#xff0c;使用HDrawingObject、HDrawingObjectXld&#xff0c;绘制矩形、方向矩形、圆形、椭圆、自定义ROI。支持拖动、重设大小、选中。 运行结果 代码 代码结构 MainForm 视图 MainViewModel 视图模型 ROI R…

Visual Studio 使用 GitHub Copilot 与 IntelliCode 辅助编码 【AI辅助开发系列】

&#x1f380;&#x1f380;&#x1f380;【AI辅助编程系列】&#x1f380;&#x1f380;&#x1f380; Visual Studio 使用 GitHub Copilot 与 IntelliCode 辅助编码Visual Studio 安装和管理 GitHub CopilotVisual Studio 使用 GitHub Copilot 扩展Visual Studio 使用 GitHu…