06-限流策略有哪些,滑动窗口算法和令牌桶区别,使用场景?【Java面试题总结】

news2024/11/28 4:42:55

限流策略有哪些,滑动窗口算法和令牌桶区别,使用场景?

常见的限流算法有固定窗口、滑动窗口、漏桶、令牌桶等。

6.1 固定窗口

概念:固定窗口(又称计算器限流),对一段固定时间窗口内的请求进行一个计数,如果请求数量超过阈值,就会舍弃这个请求,如果没有达到设定阈值,就直接接受这个请求。

public class FixedWindowRateLimiter1 {
    private final int windowSize;
    private final int limit;
    private final AtomicInteger count;
    private final ReentrantLock lock;

    public FixedWindowRateLimiter1(int windowSize, int limit) {
        this.windowSize = windowSize;
        this.limit = limit;
        this.count = new AtomicInteger(0);
        this.lock = new ReentrantLock();
    }

    public boolean allowRequest() {
        lock.lock();
        try {
            long currentTimestamp = Instant.now().getEpochSecond();
            int currentCount = count.get();
            if (currentCount < limit) {
                count.incrementAndGet();
                return true;
            } else {
                return false;
            }
        } finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        FixedWindowRateLimiter1 rateLimiter = new FixedWindowRateLimiter1(5, 3);

        // 测试通过的请求
        for (int i = 0; i < 10; i++) {
            if (rateLimiter.allowRequest()) {
                System.out.println("Request " + (i + 1) + ": Allowed");
            } else {
                System.out.println("Request " + (i + 1) + ": Denied");
            }
            TimeUnit.SECONDS.sleep(1);
        }
    }
}

在上述代码中,我们引入了 ReentrantLockAtomicInteger,分别用于保证线程安全的访问和原子的计数操作。通过在 allowRequest() 方法中使用 lock 对关键代码段进行加锁和解锁,确保同一时间只有一个线程能够进入关键代码段。使用 AtomicInteger 来进行计数操作,保证计数的原子性。

6.2 滑动窗口

概念:滑动窗口算法是一种基于时间窗口的限流算法,它将时间划分为固定大小的窗口,并统计每个窗口内的请求数量。算法维护一个滑动窗口,窗口内的位置表示当前时间片段,每个位置记录该时间片段内的请求数量。当请求到达时,算法会根据当前时间判断应该归入哪个时间片段,并检查该时间片段内的请求数量是否超过限制。

以滑动窗口算法为例,每秒最多允许通过3个请求

public class SlidingWindowRateLimiter {
    private final int limit; // 限流阈值
    private final int interval; // 时间窗口长度
    private final AtomicLong counter; // 计数器
    private final long[] slots; // 时间窗口内每个时间片段的请求数量
    private long lastTimestamp; // 上次请求时间
    private long currentIntervalRequests; // 当前时间窗口内的请求数量

    public SlidingWindowRateLimiter(int limit, int interval) {
        this.limit = limit;
        this.interval = interval;
        this.counter = new AtomicLong(0);
        this.slots = new long[interval];
        this.lastTimestamp = System.currentTimeMillis();
        this.currentIntervalRequests = 0;
    }

    public boolean allowRequest() {
        long currentTimestamp = System.currentTimeMillis();
        if (currentTimestamp - lastTimestamp >= interval) {
            // 超过时间窗口,重置计数器和时间窗口
            counter.set(0);
            slots[0] = 0;
            lastTimestamp = currentTimestamp;
            currentIntervalRequests = 0;
        }

        // 计算请求数量
        long currentCount = counter.incrementAndGet();
        if (currentCount <= limit) {
            // 未达到阈值,请求通过
            slots[(int) (currentCount - 1)] = currentTimestamp;
            currentIntervalRequests++;
            return true;
        }

        // 达到阈值,判断最早的时间片段是否可以通过
        long earliestTimestamp = slots[0];
        if (currentTimestamp - earliestTimestamp >= interval) {
            // 最早的时间片段超过时间窗口,重置计数器和时间窗口
            counter.set(0);
            slots[0] = 0;
            lastTimestamp = currentTimestamp;
            currentIntervalRequests = 0;
            return true;
        }

        return false;
    }

    public long getRequestsPerSecond() {
        return currentIntervalRequests * 1000 / interval;
    }
}
public class SlidingWindowRateLimiterTest {
    public static void main(String[] args) throws InterruptedException {
        // 创建一个限流器,限制每秒最多通过3个请求
        SlidingWindowRateLimiter rateLimiter = new SlidingWindowRateLimiter(3, 1000);

        // 模拟连续发送请求
        long startTime = System.nanoTime();
        for (int i = 1; i <= 10; i++) {
            if (rateLimiter.allowRequest()) {
                System.out.println("Request " + i + " allowed");
            } else {
                System.out.println("Request " + i + " blocked");
            }
            Thread.sleep(100); // 模拟请求间隔时间
        }
        System.out.println((System.nanoTime()-startTime)/1000000000.0);
    }
}

image-20230831002052894

6.3 令牌桶算法

概念:令牌桶算法基于令牌的发放和消耗机制,令牌以固定的速率被添加到令牌桶中。每个请求需要消耗一个令牌才能通过,当令牌桶中的令牌不足时,请求将被限制。令牌桶算法可以平滑地限制请求的通过速率,对于突发流量有较好的处理能力。

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

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

相关文章

1780_添加鼠标右键空白打开命令窗功能

全部学习汇总&#xff1a; GitHub - GreyZhang/windows_skills: some skills when using windows system. 经常执行各种脚本&#xff0c;常常需要切换到命令窗口中输入相关的命令。从开始位置打开cmd然后切换目录是个很糟糕的选择&#xff0c;费时费力。其实Windows 7以及Windo…

鸿蒙学习笔记之资源管理器(十一)

本次要点&#xff1a; 1.什么是资源管理器 2.资源管理器的应用 1.什么是资源管理器 资源管理器是系统提供的资源管理工具&#xff0c;我们可以用它查看本台电脑的所有资源&#xff0c;特别是它提供的树形的文件系统结构&#xff0c;使我们能更清楚、更直观地认识电脑的文件和…

学会Mybatis框架:让你的开发事半功倍【五.Mybatis关系映射】

目录 &#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 导语 一、一对一的关系映射 1.表结构 2.resultMap配置 3.测试关系映射 二、一对多的关系映射 1.表结构 2.resultMap配置 3.测试关系映射 三、多对多的关系映射 1.表结构…

一文讲通嵌入式现状

近年来&#xff0c;随着计算机技术和集成电路技术的迅速发展&#xff0c;嵌入式技术在通讯、网络、工控、医疗、电子等领域日益普及&#xff0c;并发挥着越来越重要的作用。嵌入式系统已成为当前最为热门和前景广阔的IT应用领域之一。 随着信息化、智能化、网络化的不断推进&am…

基于Citespace、vosviewer、R语言的文献计量学可视化分析技术及全流程文献可视化SCI论文高效写作

文献计量学是指用数学和统计学的方法&#xff0c;定量地分析一切知识载体的交叉科学。它是集数学、统计学、文献学为一体&#xff0c;注重量化的综合性知识体系。特别是&#xff0c;信息可视化技术手段和方法的运用&#xff0c;可直观的展示主题的研究发展历程、研究现状、研究…

ARM DIY(七)麦克风调试

前言 上篇文章介绍了扬声器调试&#xff0c;今天介绍下麦克风调试。 硬件 焊接&#xff1a;咪头、电阻、电容 驱动 && 应用程序 音频调试时已完成&#xff0c;参考上篇文章 测试 使能 mic1 # ./amixer -c 0 cset numid12 2 numid12,ifaceMIXER,nameMic1 Captu…

【杂言】写在研究生开学季

这两天搬进了深研院的宿舍&#xff0c;比中南的本科宿舍好很多&#xff0c;所以个人还算满意。受台风 “苏拉” 的影响&#xff0c;原本的迎新计划全部打乱&#xff0c;导致我现在都还没报道。刚开学的半个月将被各类讲座、体检以及入学教育等活动占满&#xff0c;之后又是比较…

【数据结构篇】线性表1 --- 顺序表、链表 (万字详解!!)

前言&#xff1a;这篇博客我们重点讲 线性表中的顺序表、链表 线性表&#xff08;linear list&#xff09;是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构&#xff0c;常见的线性表&#xff1a;顺序表、链表、栈、队列... 线性表在逻辑上是…

【learnopengl】Assimp构建与编译

文章目录 【learnopengl】Assimp构建与编译1 前言2 Assimp构建与编译2.1 下载源码2.2 CMake构建2.3 VS2022编译 3 在VS中配置Assimp库4 验证 【learnopengl】Assimp构建与编译 1 前言 最近在跟着LearnOpenGL这个网站学习OpenGL&#xff0c;这篇文章详细记录一下教程中关于Ass…

vue的第3篇 第一个vue程序

一 vue的mvvm实践者 1.1 介绍 Model&#xff1a;模型层&#xff0c; 在这里表示JavaScript对象 View&#xff1a;视图层&#xff0c; 在这里表示DOM(HTML操作的元素) ViewModel&#xff1a;连接视图和数据的中间件&#xff0c; Vue.js就是MVVM中的View Model层的实现者 在M…

SpringBoot复习:(60)文件上传的自动配置类MultipartAutoConfiguration

可以看到&#xff0c;定义了一个类型为StandartServletMultipartResolver的bean 用来进行文件上传&#xff0c;定义了一个类型为MultipartConfigElement的bean用来进行上传相关的配置&#xff0c;其中使用了MultipartProperties中的属性&#xff0c;这个类的定义如下&#xff1…

【Day-27满就是快】代码随想录-二叉树-二叉树的最大深度

给定一个二叉树&#xff0c;找出其最大深度。 二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。 说明: 叶子节点是指没有子节点的节点。 ———————————————————————————————————— 1. 递归法 可以使用前序和后序遍历。前序就是…

Linux Day12 ---进程间通信

一、管道 1.1 有名管道 有名管道可以在任意两个进程之间通信 1.1.1 有名管道的创建&#xff1a; 命令创建&#xff1a; mkfifo 管道名 系统调用创建 1.1.2 与普通文件区别 打开管道文件&#xff0c;在内存分配一块空间&#xff0c;往管道文件里面写数据&#xff0c;实际是…

产品思维用户思维

用户思维是一种关注用户需求、体验和价值的思维方式,将用户放在产品设计、开发和提供服务的核心位置。它强调了理解用户在不同场景下的需求,提供与之相匹配的解决方案,从而帮助用户实现他们的目标。 描述一个用户时,可以从不同角度来考虑: 按人口属性描述用户: 个人属性…

【python】reshape的使用

import numpy as np x np.array([1,2,3]) print(fx.shape{x.shape}) print(fx.reshape((1,-1)){x.reshape((1,-1))}) print(fx.reshape(3,){x.reshape(3,)}) print(fx.reshape(3,1)\n{x.reshape(3,1)}) print(fx[:,np.newaxis]\n{x[:,np.newaxis]})

IDEA中Run/Debug Configurations添加VM options和Program arguments

1. 现象描述 我在我的IDEA当中打开配置模板后&#xff0c;发现没有VM options和Program arguments&#xff0c;也就是虚拟机选项和程序实参这两项&#xff0c;导致我不能配置系统属性参数和命令行参数&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff0…

Navicat连接数据库报2003错误解决办法

是防火墙还没有开启 查看防火墙管理的端口 设置3306防火墙开启&#xff0c;重载防火墙 连接成功

java实现粤语歌曲0243填词法

粤语歌曲填词法 一、前言 转化成数字歌。对每个音符&#xff0c;提供配合广东话声调的字&#xff0c;选出成为歌词。可以在网上创作&#xff0c;或下载到自己电脑中使用。 简谱 3656536&#xff0c;歌词 落花满天蔽月光。 唱起来配合乐曲音调。这叫做‘叶韵’&#xff0c;又叫…

基于Open3D的点云处理17-Open3d的C++版本

参考&#xff1a; http://www.open3d.org/docs/latest/cpp_api.htmlhttp://www.open3d.org/docs/latest/getting_started.html#chttp://www.open3d.org/docs/release/cpp_project.html#cplusplus-example-projecthttps://github.com/isl-org/open3d-cmake-find-packagehttps:/…

数学建模:相关性分析

&#x1f506; 文章首发于我的个人博客&#xff1a;欢迎大佬们来逛逛 数学建模&#xff1a;相关性分析 文章目录 数学建模&#xff1a;相关性分析相关性分析两变量的相关分析PearsonSpearmanKendall tua-b 双变量关系强度测量的指标相关系数的性质代码实现example偏相关分析 相…