Guava RateLimiter预热模型

news2024/11/19 0:45:54

本文已收录至我的个人网站:程序员波特,主要记录Java相关技术系列教程,共享电子书、Java学习路线、视频教程、简历模板和面试题等学习资源,让想要学习的你,不再迷茫。

什么是流量预热

我们都知道在做运动之前先得来几组拉伸之类的动作,给身体做个热身,让我们的身体平滑过渡到后面的剧烈运动中。流量预热也是一样的道理,对限流组件来说,流量预热就类似于一种热身运动,它可以动态调整令牌发放速度,让流量变化更加平滑。

我们来举一个例子:某个接口设定了100个Request每秒的限流标准 ,同时使用令牌桶算法做限流。假如当前时间窗口内都没有Reques t过来,那么令牌桶中会装满100个令牌。如果在下一秒突然涌入100个请求,这些请求会迅速消耗令牌,对服务的瞬时冲击会比较大。因此我们需要一种类似“热身运动”的缓冲机制,根据桶内的令牌数量动态控制令牌的发放速率,让忙时流量和闲时流量可以互相平滑过渡。

流量预热的做法

我们以Guava中的RateLimiter为例,看看流量预热在RateLimiter中是如何运作的,我们用下面的状态转换图来展示整个过程:

横坐标是令牌桶的当前容量,纵坐标是令牌发放速率,我们先从横坐标来分析

横坐标

下面两种场景会导致横坐标的变化:

  1. 闲时流量流量较小或者压根没流量的时候,横坐标会逐渐向右移动,表示令牌桶中令牌数量增多
  2. 忙时流量当访问流量增大的时候,横坐标向左移动,令牌桶中令牌数量变少

横轴有两个重要的坐标,一个是最右侧的“令牌桶最大容量”,这个不难理解。还有一个是Half容量,它是一个关键节点,会影响令牌发放速率。

纵坐标

纵坐标表示令牌的发放速率,这里有3个标线,分别是稳定时间间隔,2倍间隔,3倍间隔。

这里间隔的意思就是隔多长时间发放一个令牌,而所谓稳定间隔就是一个基准时间间隔。假如我们设置了每秒10个令牌的限流规则,那么稳定间隔也就是1s/10=0.1秒,也就是说每隔0.1秒发一个令牌。相应的,3倍间隔的数值是用稳定间隔乘以系数3,比如上面这个例子中3倍间隔就是0.3秒。

运作模式

了解了横坐标和纵坐标的含义之后,让我们来试着理解预热模型的用例。继续沿用上面10r/s的限流设置,稳定间隔=0.1s,3x间隔是0.3s。

我们先考虑闲时到忙时的流量转变,假定当前我们处于闲时流量阶段,没几个访问请求,这时令牌桶是满的。接着在下一秒突然涌入了10个请求,这些请求开始消耗令牌桶中的令牌。在初始阶段,令牌的放行速度比较慢,在第一个令牌被消耗以后,后面的请求要经过3x时间间隔也就是0.3s才会获取第二块令牌。随着令牌桶中令牌数量被逐渐消耗,当令牌存量下降到最大容量一半的时候(Half位置),令牌放行的速率也会提升,以稳定间隔0.1s发放令牌。

反过来也一样,在流量从忙时转变为闲时的过程中,令牌发放速率是由快到慢逐渐变化。起始阶段的令牌放行间隔是0.1s,随着令牌桶内令牌逐渐增多,当令牌的存量积累到最大容量的一半后,放行令牌的时间间隔进一步增大为0.3s。

RateLimiter正是通过这种方式来控制令牌发放的时间间隔,从而使流量的变化更加平滑。

核心代码

理解了预热模型的运作流程之后,我们来看一下具体代码是如何实现的。

实现流量预热的类是SmoothWarmingUp,它是SmoothRateLimiter的一个内部类,我们重点关注一个doSetRate方法,它是计算横纵坐标系关键节点的方法,先来看一下SmoothRateLimiter这个父类中定义的方法

//permitsPerSecond表示每秒可以发放的令牌数量
@Override
final void doSetRate(double permitsPerSecond, long nowMicros) {
  resync(nowMicros);
  
  //计算稳定间隔,使用1s除以令牌桶容量
  double stableIntervalMicros = SECONDS.toMicros(1L);
  this.stableIntervalMicros = stableIntervalMicros;
  
  //调用SmoothWarmingUp类中重载的doSetRate方法
  doSetRate(permitsPerSecond, stableIntervalMicros); 
}

父类在这里的作用主要是计算出了稳定时间间隔(使用1s/每秒放行数量的公式来计算得出),然后预热时间、三倍间隔等是在子类的doSetRate方法中实现的。

接下来我们看子类SmoothWarmingUp中的doSetRate做了什么

@Override
void doSetRate(double permitsPerSecond, double stableIn tervalMicros) {
  double oldMaxPermits = maxPermits;
  
  //maxPermits表示令牌桶内最大容量,它由我们设置的预热时间除以稳定时间间隔
  maxPermits = warmupPeriodMicros / stableIntervalMicros

  //这句不用解释了吧,halfPermits是最大容量的一半halfPermits =maxPermits / 2.0;
  // coldIntervalMicros就是我们前面写到的3倍间隔,通过稳定间//稳定间隔是0.1,3倍间隔是0.2,那么平均间隔是0.2
  double coldIntervalMicros = stableIntervalMicros * 3

  //slope的意思是斜率,也就是前面我们图中预热阶段中画出的斜线//它的计算过程就是一个简单的求斜率公式
  slope = (coldIntervalMicros - stableIntervalMicros)

  //计算目前令牌桶的令牌个数
  if (oldMaxPermits == Double.POSITIVE_INFINITY) {
    //如果令牌桶最大容量是无穷大,则设置当前可用令牌数为0 //说实话这段逻辑没什么用
    storedPermits = 0.0;
  } else {
    storedPermits = (oldMaxPermits == 0.0) 
      ? maxPermits//初始化的状态是3x间隔
      : storedPermits * maxPermits / oldMaxPermits;
  }
}

通过上面的两个函数,RateLimiter限流器就对maxPermitsslope(预热期斜率)两个变量做了初始化配置。我把关键步骤都注释在了代码里,大家理解了之后,可以尝试去阅读这个类的其他方法,弄清maxPermitsslope是如何影响令牌发放速率的。

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

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

相关文章

GPT的版本发展历史及特点

版本介绍 GPT(Generative Pre-trained Transformer)是一系列基于Transformer架构的预训练语言模型,由OpenAI推出。以下是GPT的版本发展、特点和区别: GPT-1 GPT-1是最早发布的版本,于2018年发布。它具有1.17亿个参数&…

反爬虫策略:使用FastAPI限制接口访问速率

目录 引言 一、网络爬虫的威胁 二、FastAPI 简介 三、反爬虫策略 四、具体实现 五、其他反爬虫策略 六、总结 引言 在当今的数字时代,数据已经成为了一种宝贵的资源。无论是商业决策、科学研究还是日常生活,我们都需要从大量的数据中获取有价值的…

dhcp 时间同步 详细介绍

装服务程序步骤 1.如果有默认配置 请先备份 再进行修改 2.修改完配置文件 请重启服务或重新加载配置文件 否则不生效 注意:有的软件 安装包的名字和 系统里服务程序的名字不一样 htttp httpd openssh-server ssh 高阶级改防火墙 一, dhcp自动分配IP地…

中国关心下一代工作委员会健康体育发展中心美育舞蹈考官一王雪

王雪—— 《中国关心下一代工作委员会》健康体育发展中心、美育舞蹈考官、评委 北京舞蹈学院舞蹈编导 朝阳区小红门地区文化艺术-领头人 中国舞舞蹈家协会会员 2019年7月7日中国观网第六届京津冀淑女 2021年辅导学生登上央视春晚 《听我说》 2023年4月22日带学生参加万人…

资深老鸟总结,性能测试体系-知识分享,测试之路养成...

目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 开始性能测试前需…

【Python】Pyside2 可视化实现:每秒复制源文件一行到目标文件并打印日志

背景: 博主在某个项目中,需要模拟每秒钟生成一行数据,所以有了该博客的想法,其中有线程的内容,为了防止主界面卡住 效果: 代码: import sys import threading import timeimport openpyxl im…

盛元广通实验动物中心饲养管理系统2.0

盛元广通实验动物中心饲养管理系统2.0主要功能包括:访客登记、笼位/架管理、笼位预约、动物订购、伦理审查、谱系管理、饲养繁育管理、动物房消毒管理、费用管理、垫料管理等功能。实验室动物中心饲养管理系统是一个综合性的管理平台,主要用于实验动物的…

MySQL 删除ibdata1时怎么恢复

标题:MySQL InnoDB数据恢复,丢失ibdata1时怎么安全恢复 废话在前: 恭喜你,当你看到这篇文章的时候,说明有可能 你心里已经有一万匹🐎在奔腾了。千万不要乱删除ibdata1,有些博客无脑抓取、复制…

项目经理如何提高自己和团队的效率?

技术人员和管理人员,两者是不同的。当有一天领导将你从一线技术人员被提拔为项目经理,也许这是你一直期盼的,也许这使你忐忑不安,也许这是你职业发展的转折,而你当时可能只是不情愿地答应老板“试一下”。 不管哪种情…

AWS边缘媒体安全交付方案

企业如何在AWS上的边缘站点,安全的将优质视频内容交付给用户,并且禁止哪些未经过授权的访问?九河云将基于AWS平台提供边缘媒体安全交付解决方案 解决方案详情 在通过 Amazon CloudFront 交付时,免受未经授权的访问。基于添加到交…

构建基于RHEL9系列(CentOS9,AlmaLinux9,RockyLinux9等)的支持63个常见模块的PHP8.1.20的RPM包

本文适用:rhel9系列,或同类系统(CentOS9,AlmaLinux9,RockyLinux9等) 文档形成时期:2023年 因系统版本不同,构建部署应略有差异,但本文未做细分,对稍有经验者应不存在明显障碍。 因软件世界之复杂和个人能力…

信息之板:数据看板如何点亮我们的生活

数据看板,作为数据可视化的一种应用形式,已经逐渐渗透到我们的日常生活中,发挥着越来越重要的作用。这种集中呈现和分析信息的工具,不仅在企业管理中大放异彩,更在我们的日常生活中展现出了强大的价值。下面我就以可视…

力扣精选算法100题——水果成篮(滑动窗口专题)

本题链接👉水果成篮 第一步:了解题意 我就按照实例1来进行对这题的理解。 1代表种类类型,这个数组里面有2个种类类型 ps:种类1和种类2 ,只不过种类1是有2个水果,种类2有一个水果,共计3个水果。 本题需要解…

Transformer原理与代码实现

Transformer原理与代码实现 概览 一、嵌入层 Embedding 二、位置编码 Positional Encoding 三、(整合)Transformer嵌入层 Transformer Embedding 四、带缩放的点积注意力机制 Scaled Dot-Product Attention 五、多头注意力 Multi-Head Attention 六…

simulink之Data Type Conversion

Data Type Conversion 将输入信号转换为指定的数据类型。 数据类型转换块将任何Simulink数据类型的输入信号转换为您为输出数据类型参数指定的数据类型。输入可以是任何实值或复值信号。如果输入是真实的,那么输出就是真实的。如果输入是复杂的,那么输出…

日处理100立方污水的污水成套设备需要哪些

对于处理100立方污水的污水成套设备,我们可以选择以下几种设备来完成任务。首先,我们需要一个污水处理设备,它可以帮助我们去除污水中的固体悬浮物和污染物。这个设备可以将污水中的固体物质过滤掉,使水变得清澈透明。同时&#x…

SQL语句错误this is incompatible with sql_mode=only_full_group_by解决方法

一、原理层面 这个错误发生在mysql 5.7.5 版本及以上版本会出现的问题: mysql 5.7.5版本以上默认的sql配置是:sql_mode“ONLY_FULL_GROUP_BY”,这个配置严格执行了"SQL92标准"。 很多从5.6升级到5.7时,为了语法兼容,大部…

如何做用户分层和标签体系

“活动作了一场接一场,简直要累死了,拉进来的客户也没有多少,投入产出完全不成比例,怎么办?“ “有那么多注册用户,但是GMV怎么才这么点,他们怎么不买啊,难道都是羊毛党?…

CompletableFuture原理与用法

CompletableFuture 是由Java8引入的,这让我们编写清晰可读的异步代码变得更加容易,该类功能比Future 更加强大。 什么是 CompletableFuture 在Java中CompletableFuture用于异步编程,异步通常意味着非阻塞,运行任务单独的线程&…

muduo网络库剖析——套接字Socket类

muduo网络库剖析——套接字Socket类 前情从muduo到my_muduo 概要socket网络编程socket编程接口介绍头文件socketbindlistenacceptaccept4connect 框架与细节成员函数使用方法 源码结尾 前情 从muduo到my_muduo 作为一个宏大的、功能健全的muduo库,考虑的肯定是众多…