限流算法(令牌桶漏桶计数器)

news2024/11/28 1:42:57

       📝个人主页:五敷有你      
 🔥系列专栏:Spring
⛺️稳中求进,晒太阳

业务重的三种情况:突发流量、恶意流量、业务本身需要

限流:   是为了保护自身系统和下游系统不被高并发流量冲垮,导致系统雪崩。

保证系统在可用的情况下尽可能增加进入的请求,其余的请求在排队等待,或者返回友好提示。保证进入系统的用户可以友好使用。

令牌桶算法

令牌桶算法是一个设定的速率产生令牌(token) 并放入令牌通,每次用户请求都得申请令牌。如果令牌不足,则拒绝请求。

        令牌桶算法中新请求到来时会从桶中拿走一个令牌,如果桶内没有i令牌可拿,就拒绝服务。

        当然令牌的数量也是有上限的。令牌的数量与时间和发放速率强相关。时间流逝的时间越长,会不断往桶里加入越多的令牌,如果令牌发送的速度比申请速度快,令牌会放满令牌桶,直到令牌占满令牌桶

令牌桶的算法特点:

好处:可以方便地应对突发出口流量。

比如:可以改变令牌发放速度(需要后端系统能力的提升),算法能按照新的发送速率调大令牌的发放数量,使得出口突发流量能被处理。

令牌生成的速度固定,消费速度不固定。

代码简单实现:

package ratelimit;


import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Logger;


public class TokenBucketLimiter {


    //桶的容量
    private static int capacity=100;
    //令牌生成速度 rate/s
    private static final int rate=50;
    //令牌数量
    private volatile static AtomicInteger tokens=new AtomicInteger(0);

    /**
     * 开启一个线程,按固定频率放入令牌桶固定个数
     */
    public static void productTokens(){
        ScheduledExecutorService scheduledExecutorService= Executors.newScheduledThreadPool(1);
        scheduledExecutorService.scheduleAtFixedRate(()->{
            int allTokens = tokens.get()+rate;
            //设置当前的tokens数量
            tokens.set(allTokens);
        },1000,1000,TimeUnit.MILLISECONDS);

    }


    /**
     * true是被限流了
     *
     * @param needCount
     * @return
     */
    public static synchronized boolean limited(int needCount){
        if(tokens.get()<needCount){

            return true;
        }

        System.out.println("此时令牌桶中数量有: "+tokens.getAndDecrement());
        return false;
    }
    public static void main(String[] args) {
        //开启生产者任务
        productTokens();
        //定义一个原子类,
        AtomicInteger atomicInteger=new AtomicInteger(0);
        ExecutorService executorService=Executors.newFixedThreadPool(5);
        for(int i=0;i<10000;i++){
            executorService.submit(()->{
                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                //当前线程的名称
                String taskName=Thread.currentThread().getName();
                boolean isLimit=limited(1);
                //true被限流了
                if(isLimit){
                    System.out.println(taskName+"被限流了,累计限流次数: "+atomicInteger.incrementAndGet());
                }else {
                    System.out.println(taskName+"请求被正常处理了");
                }
            });

        }



    }




}

 

漏桶算法

漏桶(Leak Bucket) 算法限流的基本原理:

水(对应请求) 从进水口到漏桶里,漏桶以一定的速度出水(请求放行),当水流速度过大,桶内的总水量大于桶容量会直接溢出,请求拒绝。

大致的规则如下:

1)进水口(对应客户端请求) 以任意速率流入漏桶。

2)漏桶的容量是固定的,出水(放行)速率也是固定的。

3)漏桶容量是不变的,如果处理速度太慢,桶内水的容量就会超出桶的容量,则后面的水滴会标识请求拒绝。

流程:

水(请求)先进入桶中,漏桶按照一定的速率进行漏水,如果漏桶满了,那么水就会溢出(请求拒绝),可以看出来漏桶算法能强行限制数据的传输速率。

代码实现

package ratelimit;

import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

public class LeakBucketLimiter {
    //漏桶的容量
    private static int capacity=10;
    //漏水的速度 rate/s
    private static final int leakRate=5;
    //桶中水量
    private volatile static AtomicInteger waterLeaf=new AtomicInteger(0);

    /**
     * 开启一个线程,按固定频率放入令牌桶固定个数
     */
    public static void leakWater(){
        ScheduledExecutorService scheduledExecutorService= Executors.newScheduledThreadPool(1);
        scheduledExecutorService.scheduleAtFixedRate(()->{
            //现在桶中的水
            int water = waterLeaf.get()-leakRate;
            //设置当前的水量
            waterLeaf.set(Math.max(0,water));
        },1,1, TimeUnit.SECONDS);

    }
    public static synchronized boolean limited(int waterCount){
        if(waterLeaf.get()+waterCount>capacity){
            //水满了拒绝
            return true;
        }
        waterLeaf.addAndGet(waterCount);
        System.out.println("此时漏桶水量有: "+waterLeaf);
        return false;
    }
    public static void main(String[] args) {

        //开始漏水
        leakWater();

        //开启请求
        ScheduledExecutorService executorService=Executors.newScheduledThreadPool(5);
        AtomicInteger atomicInteger=new AtomicInteger(0);
        for(int i=0;i<10000;i++){
            executorService.submit(()->{
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                String taskName=Thread.currentThread().getName();
                boolean limited = limited(1);
                if(limited){
                    System.out.println(taskName+"请求被拦截,累计拦截次数"+atomicInteger.incrementAndGet());
                }else{
                    System.out.println(taskName+"请求访问成功!!!");
                }
            });

        }



    }


}

计数器算法

        计数器算法在一段时间间隔内(时间窗/时间区间),处理请求的最大数量固定,超过部分不做处理。计数器算法是限流算法中最简单的,也是最容易实现的一种算法。

举个例子:

比如:我们规定对于A接口,我们一分钟访问次数不能超过100个。

可以这么做:

1. 在一开始的时候,我们可以设置一个计数器counter,每当一个请求过来的时候,counter就+1,如果counter的值大于100,并且该请求与第一个请求的间隔在一分钟之内,那么说明请求数过多,拒绝访问;

2. 如果该请求与第一个请求的间隔时间大于1分钟,且counter的值还在限流范围内,那么重置counter,就是这么简单粗暴

问题:临界问题

计数器限流的严重问题:这个算法虽然简单,但是有一个十分致命的问题,就是临界问题

两分钟之间的临界突发200请求,很危险!!!

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

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

相关文章

jQuery-2.鼠标焦点事件、节点操作、遍历元素、效果

鼠标事件 鼠标事件是当用户在文档上移动或单击鼠标时而产生的事件&#xff0c;常用的鼠标事件&#xff1a; 方法 描述 执行时机 click() 触发或将函数绑定到指定元素的click事件 单击鼠标时 mouseover() 触发或将函数绑定到指定元素的mouse over事件 鼠标移过时 mous…

体重秤蓝牙语音芯片方案-WT2605蓝牙音频ic在电子秤上的应用

在快节奏的现代生活中&#xff0c;健康成为了每个人关注的焦点。而体重作为健康指标之一&#xff0c;更是备受关注。如今&#xff0c;一款全新的智能体重秤蓝牙语音芯片方案正悄然改变着我们的健康管理方式&#xff0c;让健康触手可及。 性能&#xff1a; 1&#xff1a;蓝牙语…

.Net8.0 Blazor Hybird 桌面端 (WPF/Winform) 发布到 Win7+

.Net8.0 Blazor Hybird 桌面端 (WPF/Winform) 实测可以完整运行在 win7sp1/win10/win11. 如果用其他工具打包,还可以运行在mac/linux下, 传送门BlazorHybrid 发布为无依赖包方式 安装 WebView2Runtime 1.57 MB或136 MB 测试DEMO 发布为依赖包方式 安装 WebView2Runtime 1.…

渗透测试工具及插件第二期

一、OWASP Penetration Testing Kit 这个工具他集成了中间件&#xff0c;等版本信息&#xff0c;漏洞信息&#xff0c;url&#xff0c;标识头等信息&#xff0c;WAF/CDN识别&#xff0c;密匙等信息&#xff0c;多种信息的功能上集合的插件。 说明书&#xff1a;https://micros…

pwn(一)前置技能

以下是pwn中的题目&#xff08;漏洞&#xff09;类型&#xff1a; 关于pwn的学习&#xff1a; 一.什么是pwn&#xff1f;&#xff08;二进制的漏洞&#xff09; "Pwn"是一个俚语&#xff0c;起源于电子游戏社区&#xff0c;经常在英语中用作网络或电子游戏文化中的…

qt 5.15.x 安装android过程记录

1.经过好几天的qt for android 安装&#xff0c;发现存在很多坑 参考其他文章可以编译出APK文件。但是我发现(我的机器上)无法调试apk程序&#xff0c;不能调试那怎么行呢&#xff0c;看了很多文章都是运行出结果了就结束了。没有展示怎么调试程序。 很多文章都是建议安装JDK8…

Docker安装教程使用

一、Docker简介 什么是docker&#xff1a; docker是一个开源的应用容器引擎&#xff0c;让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux或Windows操作系统的机器上, 也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口什…

低代码在物品领用领域数字化转型的案例分析

办公用品管理数字化不仅代表了企业管理模式的革新&#xff0c;更是提升运营效率和成本控制的关键举措。通过数字化手段&#xff0c;企业能够实现采购、库存、领用等流程的自动化和智能化管理&#xff0c;大幅减少人工操作&#xff0c;提高处理速度&#xff0c;确保数据的准确性…

如何申请通配符SSL证书——值得收藏

申请通配符SSL证书的过程大致可以分为以下几个步骤&#xff1a; 1. 选择CA机构&#xff1a; 首先&#xff0c;您需要选择一个受信任的证书颁发机构&#xff08;Certificate Authority&#xff0c;简称CA&#xff09;&#xff0c;如DigiCert、GlobalSign、或JoySSL。确保所选机构…

2023年数维杯国际大学生数学建模挑战赛B题棉花秸秆热解的催化反应解题全过程论文及程序

2023年数维杯国际大学生数学建模挑战赛 B题 棉花秸秆热解的催化反应 原题再现&#xff1a; 随着全球对可再生能源需求的不断增加&#xff0c;生物质能作为一种成熟的可再生能源得到了广泛的关注。棉秆作为一种农业废弃物&#xff0c;由于其富含纤维素、木质素等生物质成分&am…

LangChain:模型 I/O 封装使用解析和感触

目录 模型 API&#xff1a;LLM vs. ChatModel OpenAI 模型封装 多轮对话 Session 封装 换个国产模型 模型的输入与输出 Prompt 模板封装 PromptTemplate ChatPromptTemplate MessagesPlaceholder 从文件加载 Prompt 模板 TXT模板 Yaml模板 Json模板 输出封装 Out…

[代码比较工具下载及使用]你真的需要一个代码比较工具

&#x1f496;&#x1f496;&#x1f496;欢迎来到我的博客&#xff0c;我是anmory&#x1f496;&#x1f496;&#x1f496; 又和大家见面了 欢迎来到资源分享系列 这里有你想要的各种高质量资源 先来自我推荐一波 个人网站欢迎访问以及捐款 推荐阅读 如何低成本搭建个人网站 …

被称为“数智化黑马”的红海云,凭何连续四年登上HR服务品牌百强榜?

近日&#xff0c;中国领先的人力资源媒体机构HRoot发布了2023年中华区人力资源服务机构品牌100强榜单。该榜单经历经十余年&#xff0c;评选标准从最初的品牌影响力&#xff0c;扩大至人力资源服务机构的财务状况、成长性、创新性等更多维度。该榜单分为人力资源服务、人力资源…

十进制整数转平衡三进制

求解原视频&#xff1a;平衡三进制 求赞&#xff01;100赞买个乒乓球拍&#xff01;_哔哩哔哩_bilibili 题目&#xff1a; 上海市计算机学会竞赛平台 | YACS 求解程序&#xff1a; using namespace std; #include <iostream> #include <cstring>string work(int n…

李廉洋:5.13黄金原油消息面面和行情分析,必看策略。

黄金方面&#xff1a;月初公布的美国非农等就业市场数据比较弱势&#xff0c;显示美国就业市场开始走软&#xff0c;美联储在就业市场开始变差的背景下&#xff0c;存在提前降息的可能性&#xff0c;这有利于推动金价走高。The         近期公布的美国5月密歇根大学消费者…

2024终南山整形美容学院首届全国腹壁整形学术交流会 国际医学顺利开展

四月芳菲尽&#xff0c;五月絮升华。5月11日&#xff0d;12日&#xff0c;《2024终南山整形美容学院首届全国腹壁整形学术交流会暨第二届崔鑫腹壁整形学习班》在西安国际医学中心医院如期召开。来自全国各大整形外科同行精英们&#xff0c;济济一堂&#xff0c;共同交流探讨腹壁…

五月采购节 | 全场板卡八七折起

淘宝搜索【北京迅为电子官方企业】 5月13日~5月15日 海量优惠券等你拿&#xff01; 复制下方链接到淘宝 直接进入店铺&#xff01; https://shop459378556.taobao.com

项目-坦克大战-让坦克动起来

为什么写这个项目 好玩涉及到java各个方面的技术 1&#xff0c;java面向对象 2&#xff0c;多线程 3&#xff0c;文件i/o操作 4&#xff0c;数据库巩固知识 java绘图坐标体系 坐标体系-介绍 坐标体系-像素 计算机在屏幕上显示的内容都是由屏幕上的每一个像素组成的像素是一…

netty配置SSL、netty配置https(生产环境)

netty配置SSL、netty配置https&#xff08;生产环境&#xff09; 上一篇提到了如何在开发环境使用SSL&#xff1a;https://lingkang.top/archives/netty-pei-zhi-ssl 转自&#xff1a;https://lingkang.top/archives/netty-pei-zhi-https 那么netty如何使用可信任的证书呢&a…

栈的实现与OJ括号匹配

今日备忘录: "不破不立. " 本文索引 1. 前言2. 顺序表与链表的区别3. 什么是栈4. 栈的实现5. OJ括号匹配6. 总结 1. 前言 人总是在坍塌中重建, 有些东西必须摧毁, 才能迎来新生, 不管是那些消耗你的人, 还是令你感到焦虑的事情, 还是一份你觉得毫无意义并且又不喜欢…