限流算法(漏桶算法、令牌桶算法)对比

限流算法(漏桶算法、令牌桶算法)

漏桶算法:

有个桶,比如最大能进2个单位的水(请求),桶底有个洞,每个单位的水都会在桶里待3秒后漏下去。
那么这个桶就可以同时处理2个单位的水。
如果进水太多,同一时间进水多出2个单位的水就溢出来了,也就是拒绝请求或阻塞。
在这里插入图片描述

令牌桶算法:

有个桶,每个固定时间会向桶里放令牌,放满就不放了,而每次请求都会从桶里去拿令牌,拿到才能正常请求。
如果拿的速度大于放的速度,那么就会出现拿不到令牌的情况,请求就会被拒绝或阻塞。
在这里插入图片描述

基于漏桶算法的典型实现:java.util.concurrent.Semaphore
基于令牌桶算法是典型实现:com.google.common.util.concurrent.RateLimiter

1、Semaphore(漏桶算法)

Semaphore更倾向于限制并发量,比如系统只支持2个并发,那么就设置:
Semaphore semaphore = new Semaphore(2);
每次请求前,执行semaphore.acquire();相当于将水放在水桶里,最多放2个
请求结束前,执行semaphore.release();相当于把水漏掉
那么效果就是系统每秒只能支持两个请求,只有等这某个请求执行完,并且释放掉,才能接收新的请求

2、RateLimiter(令牌桶算法)

RateLimiter更倾向于限制访问速率,比如系统每秒2次请求,那就设置:
RateLimiter limiter = RateLimiter.create(2.0);
每次请求前,执行limiter.acquire();相当于从桶里取令牌
那效果就是每秒只能有两个请求取到令牌,其他请求只能阻塞住,等待下一秒

刚开始看这两种限流算法,有些人会混淆,感觉不到太大的差别,那就试试跑跑下面的例子,感受一下:
    public static void main(String[] args) {RateLimiter limiter = RateLimiter.create(2.0); // 这里的2表示每秒允许处理的量为2个for (int i = 1; i <= 10; i++) {limiter.acquire();// 拿令牌,拿不到就阻塞log.info("执行。。。" + i);}}
    public static void main(String[] args) {Semaphore semaphore = new Semaphore(2);//这里的2表示并发数是2for(int i=0;i<10;i++) {new Thread(()->{try {semaphore.acquire();//入桶,放不下就阻塞log.info(Thread.currentThread().getName()+"执行");Thread.sleep(3000);//睡3秒} catch (InterruptedException e) {e.printStackTrace();}finally {semaphore.release();//释放}},"线程"+i).start();}}

注意比对结果,看for循环里每个执行的速度,你会发现:
使用Semaphore限流的,设置的并发数是2个,那么就是一下子两个一起执行,完了3秒后都执行完,释放掉,后两个再一起执行。重点是一批一批的。
使用RateLimiter限流的,每个执行都是匀速的,设置的每秒2个请求,那就基本上是0.5秒一个,匀速执行。重点是匀速。

具体执行结果可以看下图:

这个是RateLimiter,可以看到是匀速的执行,0.5秒一个。
在这里插入图片描述
这个是Semaphore,是两个两个的执行,每3秒2个。
在这里插入图片描述

注意

这两种都是单机版的,分布式环境可以使用redis等分布式唯一存储来记录这些值,原理都基本差不多

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

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

相关文章

guns框架

分享一个框架guns https://gitee.com/naan1993/guns/ 这算是国内比较优秀的框架&#xff0c;简单的套路都有。 权限啊&#xff0c;代码自动生成啊等等 快速搭建一套后台管理项目 下面是作者介绍&#xff1a; Guns基于Spring Boot2&#xff0c;致力于做更简洁的后台管理系统。…

URLDecoder: Illegal hex characters in escape (%) pattern ...

URL中含有%&#xff0c;报错如下&#xff1a; URLDecoder: Illegal hex characters in escape (%) pattern … 解决&#xff1a; uriStr uriStr.replaceAll("%","%25"); 这种情况一般是出现在连接mongoDB数据库的时候&#xff0c;因为要把用户名密码写…

[设计模式] ------ 策略模式实战:java中替代if-else的大段逻辑

java中用策略模式替代if-else的大段逻辑 问题&#xff1a; java本来是一门以面向对象为主的语言&#xff0c;但很多人嘴上说着java面向对象&#xff0c;然后除了表映射实体之外&#xff0c;其他的还是面向过程的思路。 就比如今天要说的&#xff0c;代码中大段大段的if-else判…

mongodb 索引详解

使用springboot连接mongodb的时候&#xff0c;涉及到索引的使用 举例&#xff1a; Document(collection"book") //注释的是复合索引 //CompoundIndexes( // { // CompoundIndex(name "复合索引名字",def "{字段01:1,字段02:…

[转载] --- 让线程按顺序执行8种方法

看到一篇比较用心的总结&#xff0c;涉及到很多知识点&#xff0c;转来保存&#xff0c;而且我把里面的每个方法都试了一遍&#xff0c;亲测没问题 此次转载&#xff0c;还新增了一些说明和结构 我的总结&#xff1a; 其实&#xff0c;让线程按顺序执行&#xff0c;其实就是…

mongodb数据库,批量插入性能测试记录

spring boot 框架下&#xff0c;操作mongodb数据库 maven&#xff1a;spring-data-mongodb:2.1.3.RELEASE mongo数据库用的是本地的mongo&#xff0c;所以环境不一样&#xff0c;可能结果不一样。但趋势应该是一样的。 测试保证每次批量插入时&#xff0c;库里的数据量都是一…

[转载] --- 数据库基本知识

里面的很多点&#xff0c;我之前都总结过&#xff0c;但是感觉这篇把这些都连起来了&#xff0c;总结的挺好&#xff0c;转载保存一下 【从入门到入土】令人脱发的数据库底层设计前言 说到数据库这个词&#xff0c;我只能用爱恨交加这个词来形容它。两年前在自己还单纯懵懂的时…

java中使用lua脚本

第一步&#xff1a; windows下&#xff0c;先下载安装lua&#xff08;其他操作系统自行百度&#xff0c;我只说主要基本的流程&#xff09; 下载地址 我选了lua-5.3.4_Win64_bin.zip为例 第二步&#xff1a; 解压到D盘根路径的lua文件夹中 配置环境变量&#xff0c;增加D:\l…

java中使用lua操作redis

java中使用lua脚本参见我的上一篇文章 lua基础 本篇简单说下java中使用lua操作redis的示例&#xff0c;如下&#xff1a; 先引入jedis <dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>2.9.0</…

spring-boot发送邮件失败 AuthenticationFailedException: 535 Authentication Failed

发送邮件失败&#xff0c;平时一直是好的&#xff0c;突然有天开始失败了&#xff0c;最后是发现邮箱密码失效了。。。 有的邮箱&#xff0c;需要定期更改密码。

windows本地项目开机自启动设置

记录下&#xff0c;本地项目开机自启动 vue项目 新建vue.bat文件 echo off :: nodejs安装目录下的nodevars.bat set nodevars "D:\Program Files\nodejs\nodevars.bat" :: 切换到D盘 d: :: 移动到需要启动的目录 cd D:\Users\curry.zhang\IdeaProjects\data-chec…

互联网广告行业(01)------ 初识了解DSP、SSP、ADX

最近有幸接触到公司的一个实时竞价系统&#xff0c;也算是公司的核心系统之一了&#xff0c;增加了很多新的知识&#xff0c;可能有点乱&#xff0c;先总结一波&#xff1a; 广告行业&#xff0c;先介绍概念 广告主&#xff1a;需要打广告的站点&#xff0c;一般就是卖东西的…

互联网广告行业(02)------OpenRTB(实时竞价)规范解读

RTB&#xff1a;(Real Time Bidding实时竞价)&#xff0c;RTB是一种广告交易的方式 OpenRTB&#xff1a;简单理解就是一个行业规范&#xff0c;是一个为了促进RTB方式广告的标准&#xff0c;有对应的api文档&#xff0c;大家都按照这个规范去传参数&#xff0c;那么发送方和接收…

[go]---从java到go(01)---基础与入门上手

为什么用go&#xff0c;就是为了快速响应并且高并发。 一样的逻辑&#xff0c;用java也能实现&#xff0c;但用go可能就比java快点。 如果你很熟练java了&#xff0c;那么学习go就会很快。 go的社区环境相比java没那么大&#xff0c;但一般问题都足够了。 go是谷歌出品&#xf…

[go]---从java到go(02)---一个简单的handler模式的实现

类似于责任链模式吧&#xff0c;不同类实现相同的入参&#xff0c;执行不同的操作&#xff0c;一个执行完再确定要不要执行下一个。 用go实现&#xff1a; 1.定义一个接口 后面所有的handler都要实现这个接口的handler方法 type IHandler interface {/**true 表示通过 false…

[数据库] --- clickhouse

clickhouse是一个列式数据库&#xff08;系统&#xff09;。 官方文档 官网比较全&#xff0c;但也可以说比较杂&#xff0c;下面就是我个人的一些总结&#xff0c;以及在实际工作中的应用场景。 1.clickhouse适用场景 clickhouse主要适合那种大量数据做分析的场景。 一般数据…

错误记录:expected single matching bean but found 2

springboot项目&#xff0c;之前有mysql数据源&#xff0c;现在又新增了clickhouse数据源&#xff0c;于是 新增了一个clickhouseDatasource的配置bean&#xff0c;如下&#xff1a; Beanpublic DataSource dataSource() throws PropertyVetoException {HikariConfig config …

消息队列(5):RocketMQ

介绍 RocketMQ是一款成熟的分布式消息中间件。 由阿里2012年开源&#xff0c;2017年成为Apache顶级项目。 源码是java写的。 高性能&#xff0c;低延迟&#xff0c;高可靠。历经多次双十一大促&#xff0c;整体很稳定。 RocketMQ对比其他mq的优势 对比kafka和Rabbitmq&#…

[错误记录] --- clickhouse报错Decimal value is too small

java操作clickhouse数据库&#xff0c;执行insert的时候&#xff0c;报错&#xff1a; Exception in thread "main" ru.yandex.clickhouse.except.ClickHouseException: ClickHouse exception, code: 69, host: xx.xx.xx.xxx, port: xxxx; Code: 69, e.displayText(…

[错误记录] --- rocketmq批量消费设置参数的问题

rocketmq想支持批量消费&#xff0c;于是便设置以下参数&#xff1a; consumer.setConsumeMessageBatchMaxSize(1000);这样是正确的&#xff0c;但由于业务要求&#xff0c;还想再设置大点&#xff0c;于是设置成这样&#xff1a; consumer.setConsumeMessageBatchMaxSize(10…