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

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

什么是限流?

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

限流在很多场景中用来限制并发请求量,比如说秒杀抢购、双11高并发流量等

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

限流算法

令牌桶

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

令牌桶算法中新请求到来时会从桶里拿走一个令牌,如果桶内没有令牌可拿,就拒绝服务。当然,令牌的数量也是有上限的。令牌的数量与时间和发放速率强相关,时间流逝的时间越长,会不断往桶里加入越多的令牌,如果令牌发放的速度比申请速度快,令牌桶会放满令牌,直到令牌占满整个令牌桶

在这里插入图片描述

令牌桶限流大致的规则如下:
(1)进水口按照某个速度,向桶中放入令牌。
(2)令牌的容量是固定的,但是放行的速度不是固定的,只要桶中还有剩余令牌,一旦请求过来就能申请成功,然后放行。
(3)如果令牌的发放速度,慢于请求到来速度,桶内就无令牌可领,请求就会被拒绝

总之,令牌的发送速率可以设置,从而可以对突发的出口流量进行有效的应对。

代码实现
import java.util.concurrent.*.
import java.util.concurrent.atomic.Atomiclnteger,
// 令牌桶限流算法
public class TokenBucketLimiter {
private static final int capacity= 10;//桶的容量
private static final int rate=5; //令牌生成速度 rate/s
private volatile static Atomiclnteger tokens = new Atomiclnteger(0); // 当前令牌数量// 开启一个线程放入令牌:rate/s
private static void productToken() {
//创建ScheduledThreadPool,参数为线程池的大小
ScheduledExecutorService scheduledThreadPool = Executors,newScheduledThreadPool(1)
//定时调度
scheduledThreadPool.scheduleAtFixedRate(0->{
int allTokens=tokens.get0)+rate; //计算牌数
tokens.set(Math.min(capacity, allTokens)); // 设置当前令牌数},1,1,TimeUnit.SECONDS);//延迟1秒后执行任务,并且每隔1秒执行一次
}   
特点:
  • 令牌桶的好处之一就是可以方便地应对突发出口流量。比如,可以改变令牌的发放速度(需后端系统能力的提升),算法能按照新的发送速率调大令牌的发放数量,使得出口突发流量能被处理。
  • 令牌生产速度固定,消费速度不固定。

漏桶

**漏桶(Leak Bucket)**算法限流的基本原理为:水(对应请求)从进水口进入到漏桶里,漏桶以一定的速度出水(请求放行),当水流入速度过大,桶内的总水量大于桶容量会直接溢出,请求被拒绝。

在这里插入图片描述

大致的漏桶限流规则如下:
(1)进水口(对应客户端请求)以任意速率流入进入漏桶,
(2)漏桶的容量是固定的,出水(放行)速率也是固定的,
(3)漏桶容量是不变的,如果处理速度太慢,桶内水量会超出了桶的容量,则后面流入的水滴会溢出表示请求拒绝。

水(请求)先进入到漏桶里,漏桶以一定的速度出水,当水流入速度过大会超过桶可接纳的容量时直接溢出。

可以看出漏桶算法能强行限制数据的传输速率。

漏桶算法其实很简单,可以粗略的认为就是注水漏水过程,往桶中以任意速率流入水,以一定速率流出水,当水超过桶容量(capacity)则丢弃,因为桶容量是不变的,保证了整体的速率。

代码实现
import java.util.concurrent.*,
import java.util.concurrent.atomic.Atomicinteger;
//漏桶限流算法
public class LeakyBucketLimiter {
// 计算的起始时间
private static long lastOutTime = System.currentTimeMillis(),
// 流出速率 每秒 2 次
private static int leakRate = 5
// 桶的容量
private static final int capacity = 100;
//剩余的水量
private static Atomiclnteger water = new Atomiclnteger(0);
/**
* 开启一个线程固定频率漏水:rate/s
*/
private static void waterLeaked() {
// 创建ScheduledThreadPool,参数为线程池的大小
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(1);//定时调度
scheduledThreadPool.scheduleAtFixedRate(0->{
//剩余水量
int waterLeft = water.get0) -leakRate;
// 设置当前水量
water.set(Math.max(0, waterLeft));
}.1.1,TimeUnit.SECONDS); // 延迟1秒后执行任务,并且每隔1秒执行一次   
}    
特点
  • 削峰:有大量流量进入时,会发生溢出,从而限流保护服务可用性
  • 缓冲:不至于直接请求到服务器,缓冲压力
  • 请求速度不固定,漏桶出口的速度固定,因为计算性能固定,不能灵活的应对后端能力提升。比如通过动态扩容,后端流量从1000QPS提升到10000QPS,漏桶没有办法。

令牌桶&漏桶算法区别

令牌桶:按照固定速率往桶中添加令牌
漏桶:按照常量固定速率流出请求

这两种算法的主要区别在于漏桶算法能够强行限制数据的传输速率

而令牌桶算法在能够限制数据的平均传输数据外,还允许某种程度的突发传输

在令牌桶算法中,只要令牌桶中存在令牌,那么就允许突发地传输数据直到达到用户配置的限制,因此它适合于具有突发特性的流量。

计数器

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

举个例子,比如我们规定对于A接口,我们1分钟的访问次数不能超过100个 ,可以这么做:
1.在一开 始的时候,可以设置一个计数器counter,每当一个请求过来的时候,counter就加1,如果counter的值大于100并日该请求与第一个请求的间隔时间还在1分钟之内,那么说明请求数过多,拒绝访问;
2.如果该请求与第一个请求的间隔时间大于1分钟,且counter的值还在限流范围内,那么就重置counter,就是这么简单粗暴。

代码实现
import java.util.concurrent.ExecutorService.
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.Atomiclnteger
import java.util.concurrent.atomic.AtomicLong;
/**
*计数器限流算法
*/
public class CounterLimiter {
/ 起始时间
private volatile static AtomicLong startTime = new AtomicLong(System.currentTimeMillis();
// 时间区间的时间间隔 ms
private static final long interval = 1000:
// 每秒限制数量
private static final long maxLimitCount = 10,
//累加器
private volatile static AtomicLong accumulator = new AtomicLong();
// 计数判断,是否超出限制
private static boolean isLimited(int reguestCount)long nowTime =System.currentTimeMillis0
//在时间区间之内
if (nowTime < startTime.get0 + interva)
long count=accumulator.addAndGet(reguestCount,
if (count <= maxLimitCount){
return false.
} else (
return true,
} else {
//在时间区间之外
System.out.println("新时间区到了.");
accumulator.set(0);//将计数器重新初始化为0
startTime.set(nowTime);
return false;
}}    
临界问题

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

在这里插入图片描述

从上图中我们可以看到,假设有一个恶意用户,他在0:59时,瞬间发送了100个请求,并且1:00又瞬间发送了100个请求,那么其实这个用户在1秒里面,瞬间发送了200个请求

我们刚才规定的是1分钟最多100个请求(规划的吞吐量),也就是每秒钟最多1.7个请求,用户通过在时间窗口的重置节点处突发请求,可以瞬间超过我们的速率限制。

lB2m-1731502464494)]

从上图中我们可以看到,假设有一个恶意用户,他在0:59时,瞬间发送了100个请求,并且1:00又瞬间发送了100个请求,那么其实这个用户在1秒里面,瞬间发送了200个请求

我们刚才规定的是1分钟最多100个请求(规划的吞吐量),也就是每秒钟最多1.7个请求,用户通过在时间窗口的重置节点处突发请求,可以瞬间超过我们的速率限制。

用户有可能通过算法的这个漏洞,瞬间压垮我们的应用。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

❤React-React 组件基础(类组件)

❤React-React 组件基础 1、组件化开发介绍 组件化开发思想&#xff1a;分而治之 React的组件按照不同的方式可以分成类组件&#xff1a; 划分方式一&#xff08;按照组件的定义方式&#xff09; 函数组件(Functional Component )和类组件(Class Component)&#xff1b; …

2024/11/13 英语每日一段

The new policy has drawn many critics. Data and privacy experts said the Metropolitan Transit Authority’s new initiative doesn’t address the underlying problem that causes fare evasion, which is related to poverty and access. Instead, the program tries “…

MySQL重难点(一)索引

目录 一、引子&#xff1a;MySQL与磁盘间的交互基本单元&#xff1a;Page 1、重要问题&#xff1a;为什么 MySQL 每次与磁盘交互&#xff0c;都要以 16KB 为基本单元&#xff1f;为什么不用多少加载多少&#xff1f; 2、有关MySQL的一些共识 3、如何管理 Page 3.1 单个 P…

【软件工程】一篇入门UML建模图(类图)

&#x1f308; 个人主页&#xff1a;十二月的猫-CSDN博客 &#x1f525; 系列专栏&#xff1a; &#x1f3c0;软件开发必练内功_十二月的猫的博客-CSDN博客 &#x1f4aa;&#x1f3fb; 十二月的寒冬阻挡不了春天的脚步&#xff0c;十二点的黑夜遮蔽不住黎明的曙光 目录 1. 前…

vue2+ element ui 集成pdfjs-dist

目录 1. 下载Pdf.js1.1 下载1.2 修改配置1.2.1 将pdfjs-3.8.162-dist复制到项目中1.2.2 解决跨域问题1.2.3 将pdf.worker.js文件复制到public目录下1.2.4 安装 pdfjs-dist1.2.5 前端vue代码(示例) 3. 参考资料 1. 下载Pdf.js 1.1 下载 下载链接&#xff08;官方&#xff09;需…

蓝桥杯每日真题 - 第7天

题目&#xff1a;&#xff08;爬山&#xff09; 题目描述&#xff08;X届 C&C B组X题&#xff09; 解题思路&#xff1a; 前缀和构造&#xff1a;为了高效地计算子数组的和&#xff0c;我们可以先构造前缀和数组 a&#xff0c;其中 a[i] 表示从第 1 个元素到第 i 个元素的…

大语言模型:解锁自然语言处理的无限可能

0.引言 在当今的科技时代&#xff0c;自然语言处理技术正以前所未有的速度发展&#xff0c;语言大模型作为其中的核心力量&#xff0c;对各个领域产生了深远的影响。本文旨在探讨语言大模型的发展历程、核心技术以及广泛的应用场景&#xff0c;以帮助读者更好地理解这一前沿技…

【vue2.0入门】vue基本语法

目录 引言一、页面动态插值1. 一般用法 二、计算属性computed三、动态class、style绑定四、条件渲染与列表渲染五、事件处理六、表单输入绑定七、总结 引言 本系列教程旨在帮助一些零基础的玩家快速上手前端开发。基于我自学的经验会删减部分使用频率不高的内容&#xff0c;并不…

【STM32F1】——无线收发模块RF200与串口通信

【STM32F1】——无线收发模块RF200与串口通信 一、简介 本篇主要对调试无线收发模块RF200的过程进行总结&#xff0c;实现了以下功能。 串口普通收发&#xff1a;使用STM32F103C8T6的USART2串口接收中断&#xff0c;实现两个无线收发模块RF200间的通信。 二、RF200介绍 电压…

《TCP/IP网络编程》学习笔记 | Chapter 8:域名及网络地址

《TCP/IP网络编程》学习笔记 | Chapter 8&#xff1a;域名及网络地址 《TCP/IP网络编程》学习笔记 | Chapter 8&#xff1a;域名及网络地址域名系统什么是域名&#xff1f;DNS 服务器IP 地址和域名之间的转换使用域名的必要性利用域名获取 IP 地址利用 IP 地址获取域名 基于 Wi…

前端开发中常用的包管理器(npm、yarn、pnpm、bower、parcel)

文章目录 1. npm (Node Package Manager)2. Yarn (Yarn Package Manager)3. pnpm4. Bower5. Parcel总结 前端开发中常用的包管理器主要有以下几个&#xff1a; 1. npm (Node Package Manager) 简介&#xff1a; npm 是 Node.js 的默认包管理器&#xff0c;也是最广泛使用的包…

HarmonyOS 如何实现传输中的数据加密

文章目录 摘要引言数据传输加密概述选择加密算法和传输协议加密实现方案与 Demo 代码配置 HTTPS/TLSAES 加密的实现代码详解RSA加密的实现代码详解 QA环节总结参考资料 摘要 本文将介绍在 HarmonyOS 应用中如何实现数据传输的加密策略。我们将讨论常见的加密算法&#xff08;如…

ArkTs简单入门案例:简单的图片切换应用界面

在鸿蒙 OS 应用开发的过程中&#xff0c;我们常常需要通过组合各种组件和编写相应的逻辑来实现丰富多样的功能。今天&#xff0c;我就来和大家详细解析一段实现简单图片切换功能的代码&#xff0c;希望能帮助到那些刚接触鸿蒙 OS 应用开发的朋友们。 一、代码导入部分 Entry …

influxDB 时序数据库安装 flux语法 restful接口 nodjsAPI

安装 Install InfluxDB | InfluxDB OSS v2 Documentation Debian和Ubuntu用户可以用apt-get包管理来安装最新版本的InfluxDB。 对于Ubuntu用户&#xff0c;可以用下面的命令添加InfluxDB的仓库&#xff0c;添加之后即可apt-get 安装influxdb2 wget -q https://repos.influx…

丹摩征文活动|丹摩智算平台使用指南

目录 1. 登录平台与工作环境设置1.1 访问与登录1.2 创建或选择项目1.3 初始化项目环境 2. 数据上传与管理2.1 数据上传2.2 数据管理与预处理2.3 数据可视化 3. 模型构建与训练3.1 模型选择3.2 参数配置3.3 模型训练与评估 4. 模型部署与应用4.1 模型部署4.2 接口调用与集成4.3 …

NAT网络工作原理和NAT类型

NAT基本工作流程 通常情况下&#xff0c;某个局域网中&#xff0c;只有路由器的ip是公网的&#xff0c;局域网中的设备都是内网ip&#xff0c;内网ip不具备直接与外部应用通信的能力。 处于内网的设备如何借助NAT来实现访问外网的应用&#xff1f; 对于开启了NAT功能的局域网…

LLMs 如何处理相互矛盾的指令?指令遵循优先级实验

编者按&#xff1a;想象一下&#xff0c;你正在开发一个 AI 助手&#xff0c;突然发现 system message 和用户提示词存在冲突&#xff0c;这时 AI 会听谁的&#xff1f;这种情况不仅困扰着开发者&#xff0c;还可能导致 AI 系统的不稳定和不可预测&#xff0c;影响用户体验和系…

qt QProcess详解

1、概述 QProcess是Qt框架提供的一个类&#xff0c;它用于在应用程序中执行外部进程。QProcess提供了一系列函数来启动、控制和与外部进程进行交互&#xff0c;使得开发者能够在自己的应用程序中集成和调用其他程序或服务。这个类在需要执行系统命令、启动其他应用程序或进行文…

Appium配置2024.11.12

百度得知&#xff1a;谷歌从安卓9之后不再提供真机layout inspector查看&#xff0c;仅用于支持ide编写的app调试用 所以最新版android studio的android sdk目录下已经没有了布局查看工具... windows x64操作系统 小米k30 pro手机 安卓手机 Android 12 第一步&#xff1a…

《ElementPlus 与 ElementUI 差异集合》Icon 图标 More 差异说明

参考 《element plus 使用 icon 图标(两种方式)》使用 icon 升级 Vue2 升级 Vue3 项目时&#xff0c;遇到命名时的实心与空心点差异&#xff01; ElementUI&#xff1a; 实心是 el-icon-more空心是 el-icon-more-outline ElementPlus&#xff1a; 实心是 el-icon-more-fill…