当前位置: 首页 > news >正文

限流算法深入

限流定义及目的

当系统流量达到系统或下游承受能力的阈值时对系统进行限流控制以防止系统或下游挂掉,减少影响面。

限流组成:阈值及限流策略。阈值是指系统单位时间接收到的请求qps总数;限流策略是指限流行业触发后对应的系统行为,如失败拒绝还是放入等待队列。

应用场景

如秒杀业务,商品变更消息等场景。

秒杀业务:通常来说是保护全链路系统不挂;特性是瞬时流量大;超过阈值时拒绝策略通常是返回失败。

商品变更消息:业务场景是需要将商品变更消息推送给下游商家,下游商家系统能力有限,因此需要做限制;这个场景更多是保护下游系统不挂(整条系统链路上最小短板)。

分类

4大类:计数,滑动窗口,漏桶,令牌。

计数(固定时间窗口)

单位时间窗口内进行计数,超过阈值则进行限流。

算法限制:只能限制一整秒流量。若出现第1秒中后500ms和第2秒中前500ms超过阈值则此时不生效。

实现代码

import exception.BlockException;
import java.util.concurrent.atomic.AtomicInteger;
public class CalNumProcessor {//限流窗口大小private static int WINDOW_TIME_MILL = 1000;//阈值private static final int LIMIT_NUMS = 10;//计数器private AtomicInteger count = new AtomicInteger(0);//开始时间private Long startTime;public static void main(String[] args) throws InterruptedException {CalNumProcessor calNumProcessor=new CalNumProcessor();for(int i=0;i<1000;i++){System.out.println(i);calNumProcessor.tryIncAndLimit();Thread.sleep(200);}}/*** 进行限流计数,超过限流阈值时会抛BlockException*/public void tryIncAndLimit() {//当前时间long curMill = System.currentTimeMillis();//开始时间初始化if (startTime == null) {startTime = curMill;}if ((curMill - startTime) > WINDOW_TIME_MILL) {//若时间计数超过一秒则重置计数为0并重新设置计数开始时间count.set(0);startTime = curMill;}int after = count.incrementAndGet();if (after > LIMIT_NUMS) {//超过阈值throw new BlockException();}}
}

滑动窗口

计数有个问题在于流量放大无法限流。如1秒为计数窗口。则第一秒后半秒和第二秒前半秒累计可能超过qps限制,但由于不是一个时间窗口此时反而不能限制住。

解决思路:每次请求计数每过一个时间窗口单位进行滑动计数。

整体算法思路详细

1.构建n个时间窗口单位,每个窗口单位有对应qps变量及窗口开始时间;初始化时间窗口单位的qps为0及开始时间为当前时间;

2.每次获取qps时计算当前时间应该在哪个时间窗口单位;

3.循环处理时间窗口,如果发现当前时间与时间窗口单位超过1秒(时间窗口单位最大时间)则重置窗口开始时间及qps为0。

4.将当前时间对应时间窗口qps加1;

5.返回所有时间窗口单位qps累计值;

代码实现

import java.time.LocalTime;
import java.util.concurrent.atomic.AtomicInteger;public class TimeWindow {/*** 时间窗口大小,如1秒*/private int windowTimeSize;/*** 窗口数*/private int windowNum;private Window[] windows;private int maxQps;public TimeWindow(int maxQps, int windowTimeSize, int windowNum) {this.maxQps = maxQps;this.windowTimeSize = windowTimeSize;this.windowNum = windowNum;windows = new Window[windowNum];for (int i = 0; i < windowNum; i++) {windows[i] = new Window();windows[i].setQps(new AtomicInteger(0));windows[i].setStartTime(System.currentTimeMillis());}}public static void main(String[] args) throws InterruptedException {int qps = 2;int count = 20;int sleep = 300;int success = 0;TimeWindow timeWindow = new TimeWindow(qps, 1000, 10);for (int i = 0; i < count; i++) {Thread.sleep(sleep);if (timeWindow.tryAcquire()) {success++;if (success % qps == 0) {System.out.println(LocalTime.now() + ": success, ");} else {System.out.print(LocalTime.now() + ": success, ");}} else {System.out.println(LocalTime.now() + ": fail");}}System.out.println();System.out.println("实际测试成功次数:" + success);}public boolean tryAcquire() {//计算当前时间落到哪个窗口位置int index = (int) (System.currentTimeMillis() % windowTimeSize) / (windowTimeSize / windowNum);//当前时间若超过时间累计窗口则重置窗口参数int r = 0;for (int i = 0; i < windowNum; i++) {Window curWindow = windows[i];if ((System.currentTimeMillis() - curWindow.getStartTime()) > windowTimeSize) {//当前时间减去时间窗口大于最大累计时间窗口大小则重置变量curWindow.setQps(new AtomicInteger(0));curWindow.setStartTime(System.currentTimeMillis());}//当前时间对应窗口累计qpsif (index == i) {curWindow.getQps().incrementAndGet();}r += curWindow.getQps().get();}return r <= maxQps;}class Window {/*** qps*/private AtomicInteger qps;/*** 开始时间*/private long startTime;public AtomicInteger getQps() {return qps;}public void setQps(AtomicInteger qps) {this.qps = qps;}public long getStartTime() {return startTime;}public void setStartTime(long startTime) {this.startTime = startTime;}}
}

 漏桶算法

流出衡定,不能应对突发流量,能较好保护下游。

令牌算法

优:能处理突出流量,流入相对衡定,流出允许有波动。秒杀场景适用。

这里核心概念:令牌桶(有令牌数及桶上限2个参数),令牌,获取令牌,存放令牌;

存放令牌策略有:1、有单独线路每秒加入n个令牌(相当于qps为n);2、懒计算:当获取令牌请求到来时进行计算,计算思路:Math.min(当前时间距离上次已存放令牌时间间隔秒数*令牌qps,令牌数上限)。

代码

 RateLimiter rateLimiter = RateLimiter.create(2);for (int i = 0; i < 10; i++) {String time = LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_TIME);System.out.println(time + ":" + rateLimiter.tryAcquire());Thread.sleep(250);}

实现产品

guava,阿里的sentinal。TODO。

相关文章:

限流算法深入

限流定义及目的 当系统流量达到系统或下游承受能力的阈值时对系统进行限流控制以防止系统或下游挂掉&#xff0c;减少影响面。 限流组成&#xff1a;阈值及限流策略。阈值是指系统单位时间接收到的请求qps总数&#xff1b;限流策略是指限流行业触发后对应的系统行为&#xff…...

java 基础知识 循环的几个题目

1、输出1~100的累加和 结果显示在屏幕&#xff0c;显示在文件res1.txt中 2、输出1-~100的偶数和 结果显示在屏幕&#xff0c;显示在文件res2.txt中 3、输出所有水仙花数&#xff1a; 100~999的数中出现个位数的立方十位数的立方百位数的立方这个数本身 4、输出由9行9列星号组成…...

Spring Boot使用LocalDateTime、LocalDate作为入参

0x0 背景 项目中使用LocalDateTime系列作为dto中时间的类型&#xff0c;但是spring收到参数后总报错&#xff0c;为了全局配置时间类型转换&#xff0c;尝试了如下3中方法。 注&#xff1a;本文基于Springboot2.0测试&#xff0c;如果无法生效可能是spring版本较低导致的。PS&…...

第七周第七天学习总结 | MySQL入门及练习学习第二天

实操练习&#xff1a; 1.创建一个名为 cesh的数据库 2.在这个数据库内 创建一个名为 xinxi 的表要求该表可以包含&#xff1a;编号&#xff0c;姓名&#xff0c;备注的信息 3.为 ceshi 表 添加数据 4.为xinxi 表的数据设置中文别名 5.查询 在 xinxi 表中编号 为2 的全部…...

【考研数学】线形代数第三章——向量 | 3)向量组秩的性质、向量空间、过渡矩阵

文章目录 引言三、向量组等价、向量组的极大线性无关组与秩3.2 向量组秩的性质 四、 n n n 维向量空间4.1 基本概念4.2 基本性质 写在最后 引言 紧接前文学习完向量组秩的基本概念后&#xff0c;继续往后学习向量的内容。 三、向量组等价、向量组的极大线性无关组与秩 3.2 向…...

【技术】SpringBoot Word 模板替换

SpringBoot Word 模板替换 什么是 Word 模板替换如何实现 Word 模板替换 什么是 Word 模板替换 模板一般是具有固定格式的内容&#xff0c;其中一部分需要替换。Word 模板通俗的讲是以 Word 的形式制作模板&#xff0c;固定格式和内容&#xff0c;然后将其中的一部分数据替换掉…...

java jni nv21和nv12互转

目录 libyuv性能比较 NV12 NV21 YUV420格式介绍 jni YUV420toYUV420SemiPlanar java YUV420toYUV420SemiPlanar java NV12toYUV420SemiPlanar jni NV12toYUV420SemiPlanar...

后端面试话术集锦第二篇:spring boot面试话术

🚗后端面试集锦目录 💖后端面试话术集锦第一篇:spring面试话术💖 💖后端面试话术集锦第二篇:spring boot面试话术💖 💖后端面试话术集锦第三篇:spring cloud面试话术💖 💖后端面试话术集锦第四篇:ElasticSearch面试话术💖 💖后端面试话术集锦第五篇:r…...

Doris中分区和分桶使用教程

1 分区与分桶 Doris中有两层的数据划分&#xff0c;第一层是分区&#xff08;Partition&#xff09;&#xff0c;第二层是分桶&#xff08;Bucket&#xff09;&#xff0c; Partition又能分为Range分区和List分区。 Bucket仅支持Hash方式。 1.1 Partition 只能指定…...

电脑不安装软件,怎么将手机文件传输到电脑?

很多人都知道&#xff0c;AirDroid有网页版&#xff08;web.airdroid.com&#xff09;。 想要文件传输&#xff0c;却不想在电脑安装软件时&#xff0c;AirDroid的网页版其实也可以传输文件。 然而&#xff0c;要将文件从手机传输文件到网页端所在的电脑时&#xff0c;如果按…...

vue3 publish 出现的问题

vue3项目使用 yarn build 编译出dist文件&#xff0c; 发布后出现错误 #问题与解决 1)登录迭代错误(Maximum call stack size exceeded) >deepclone 的问题 在 GrandhallLayout 中判断菜单和权限中; const mainMenu cloneDeep(router.getRoutes()) lodash.clonedee…...

网络防御和入侵检测

网络防御和入侵检测是维护网络安全的关键任务&#xff0c;可以帮助识别和阻止未经授权的访问和恶意行为。以下是一些基本的步骤和方法&#xff0c;用于进行网络防御和入侵检测。 网络防御&#xff1a; 防火墙设置&#xff1a; 部署防火墙来监控和控制网络流量&#xff0c;阻止…...

【科研论文配图绘制】task5 SciencePlots绘图包入门

【科研论文配图绘制】task5 SciencePlots绘图包入门 task5主要学习了SciencePlots拓展包的出图样式&#xff0c;掌握SciencePlots的安装及具体使用。 SciencePlots作为一个专门用于科研论文绘图的第三方拓展工具包&#xff0c;提供了主流英文科技 期刊(如 Nature、Science 和 …...

R语言常用数学函数

目录 1. - * / ^ 2.%/%和%% 3.ceiling,floor,round 4.signif,trunc,zapsamll 5.max,min,mean,pmax,pmin 6.range和sum 7.prod 8.cumsum,cumprod,cummax,cummin 9.sort 10. approx 11.approx fun 12.diff 13.sign 14.var和sd 15.median 16.IQR 17.ave 18.five…...

公网远程访问局域网SQL Server数据库

文章目录 1.前言2.本地安装和设置SQL Server2.1 SQL Server下载2.2 SQL Server本地连接测试2.3 Cpolar内网穿透的下载和安装2.3 Cpolar内网穿透的注册 3.本地网页发布3.1 Cpolar云端设置3.2 Cpolar本地设置 4.公网访问测试5.结语 1.前言 数据库的重要性相信大家都有所了解&…...

Apache Celeborn 让 Spark 和 Flink 更快更稳更弹性

摘要&#xff1a;本文整理自阿里云/数据湖 Spark 引擎负责人周克勇&#xff08;一锤&#xff09;在 Streaming Lakehouse Meetup 的分享。内容主要分为五个部分&#xff1a; Apache Celeborn 的背景Apache Celeborn——快Apache Celeborn——稳Apache Celeborn——弹Evaluation…...

华为数通方向HCIP-DataCom H12-821题库(单选题:141-160)

第141题 Router-LSA 能够描述不同的链路类型&#xff0c;不属于Router LSA 链路类型的是以下哪一项? A、Link Type 可以用来描述到末梢网络的连接&#xff0c;即 SubNet B、Link Type 可以用来描述到中转网络的连接&#xff0c;即 TranNet C、Link Type 可以用来描述到另一…...

Windows-docker集成SRS服务器的部署和使用

Windows-docker集成SRS服务器的部署和使用 一、Windows Docker安装 Docker Desktop 官方下载地址&#xff1a; https://docs.docker.com/desktop/install/windows-install/ 下载windows版本的就可以了。 注意&#xff1a;此方法仅适用于 Windows 10 操作系统专业版、企业版、…...

element-ui table表格滚动条拉到最右侧 表头与内容不能对齐

1.问题概述 当表格数据太多&#xff0c;会出现纵向滚动条和横向滚动条&#xff0c;把横向滚动条拉到最右侧时&#xff0c;会出现表头与内容不能对齐的现象。 2.解决方法 1.当页面数据加载完毕后&#xff0c;在后面加上 this.$nextTick(() > {this.$refs.table.doLayout()…...

React中的性能测试工具组件Profiler的基本使用

React中的性能测试工具组件Profiler是一个非常有用的工具&#xff0c;它可以帮助我们分析React应用程序的性能瓶颈。在本文中&#xff0c;我们将学习如何使用Profiler组件来测试React应用程序的性能。 首先&#xff0c;让我们来了解一下Profiler组件的基本用法。在React中&…...

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…...

【OSG学习笔记】Day 18: 碰撞检测与物理交互

物理引擎&#xff08;Physics Engine&#xff09; 物理引擎 是一种通过计算机模拟物理规律&#xff08;如力学、碰撞、重力、流体动力学等&#xff09;的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互&#xff0c;广泛应用于 游戏开发、动画制作、虚…...

Unity3D中Gfx.WaitForPresent优化方案

前言 在Unity中&#xff0c;Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染&#xff08;即CPU被阻塞&#xff09;&#xff0c;这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案&#xff1a; 对惹&#xff0c;这里有一个游戏开发交流小组&…...

Spring Boot 实现流式响应(兼容 2.7.x)

在实际开发中&#xff0c;我们可能会遇到一些流式数据处理的场景&#xff0c;比如接收来自上游接口的 Server-Sent Events&#xff08;SSE&#xff09; 或 流式 JSON 内容&#xff0c;并将其原样中转给前端页面或客户端。这种情况下&#xff0c;传统的 RestTemplate 缓存机制会…...

java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别

UnsatisfiedLinkError 在对接硬件设备中&#xff0c;我们会遇到使用 java 调用 dll文件 的情况&#xff0c;此时大概率出现UnsatisfiedLinkError链接错误&#xff0c;原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用&#xff0c;结果 dll 未实现 JNI 协…...

学校招生小程序源码介绍

基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码&#xff0c;专为学校招生场景量身打造&#xff0c;功能实用且操作便捷。 从技术架构来看&#xff0c;ThinkPHP提供稳定可靠的后台服务&#xff0c;FastAdmin加速开发流程&#xff0c;UniApp则保障小程序在多端有良好的兼…...

ffmpeg(四):滤镜命令

FFmpeg 的滤镜命令是用于音视频处理中的强大工具&#xff0c;可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下&#xff1a; ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜&#xff1a; ffmpeg…...

现代密码学 | 椭圆曲线密码学—附py代码

Elliptic Curve Cryptography 椭圆曲线密码学&#xff08;ECC&#xff09;是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础&#xff0c;例如椭圆曲线数字签…...

如何在最短时间内提升打ctf(web)的水平?

刚刚刷完2遍 bugku 的 web 题&#xff0c;前来答题。 每个人对刷题理解是不同&#xff0c;有的人是看了writeup就等于刷了&#xff0c;有的人是收藏了writeup就等于刷了&#xff0c;有的人是跟着writeup做了一遍就等于刷了&#xff0c;还有的人是独立思考做了一遍就等于刷了。…...

Hive 存储格式深度解析:从 TextFile 到 ORC,如何选对数据存储方案?

在大数据处理领域&#xff0c;Hive 作为 Hadoop 生态中重要的数据仓库工具&#xff0c;其存储格式的选择直接影响数据存储成本、查询效率和计算资源消耗。面对 TextFile、SequenceFile、Parquet、RCFile、ORC 等多种存储格式&#xff0c;很多开发者常常陷入选择困境。本文将从底…...