带你了解什么是限流

2022-12-11 0 597

序言

只有金发就能变弱。

文档已收录于至我的GitHub库房,热烈欢迎Star:https://github.com/ZhongFuCheng3y/3y

以后在自学的这时候也碰触不出高mammalian/大网络流量这种小东西,因此开闭总之是没碰触过的了。在看公司工程项目的这时候,发现管用到开闭(RateLimiter),Nagaur如是说新一波。

一、开闭基本知识如是说

咋要开闭,坚信就不必我多说了。

比如说,我周日去宾馆喝茶,但是人太多了,我根本无法去后台拿个号,等电话号码到我的这时候就能进宾馆喝茶。假如宾馆没有开闭咋办?一到这儿,人都DR2100冲,而宾馆又处置没法那么多人潮,很难就出交通事故(宾馆占满了人,进退两难。宾馆的值班人员崩盘了,处置不回来)返回标识符当今世界上也是那样的,伺服器能处置的允诺数非常有限,假如允诺量不光大,他们需要做开闭(或者瞧瞧允诺等候,或者就把允诺给扔了)
带你了解什么是限流

在标识符当今世界上,开闭有三种较为常用的演算法:

副本桶演算法漏桶演算法

1.1 甚么是漏桶演算法

比如说,那时我有一个罐子,绿色生态这块是我能塑料瓶的耗电量,假如少于我能真草的耗电量,再往罐子里头理发,就会外溢来(开闭):

带你了解什么是限流

他们目前能知道的是:

罐子的耗电量是一般来说的(是图上绿色生态这块)远远少于了罐子的耗电量就会外溢(或者等候,或者间接弃置)

OK,那时他们在罐子里挖个洞,让水能从磨盘里头流出:

带你了解什么是限流

罐子的出水口的大小不一是一般来说的,因此水从出水口流出的速度也是一般来说的。

因此总结下来演算法所需的参数就两个:

罐子的耗电量漏水的速度

漏桶演算法有三种实现:

不允许突发网络流量的情况:假如进水的速度大于出水的速度,间接舍弃掉多余的水。比如说,我的罐子耗电量能装100L,但我的罐子出水速度是10L/s。此时,假如那时有100L/s的水进来,我只让10L的水进到罐子,其余的都开闭。(限定了允诺的速度)允许一定的突发网络流量情况:我的罐子能装100L,假如那时我的罐子是空的,那么这100L的水都能进我的罐子。我以10L/s的速度将这些水流出,假如还有100L的水进来,根本无法开闭了。

经过上面的分析他们就知道:

漏桶演算法能平滑网络上的突发网络流量(因为漏水的速度是一般来说的)

1.2 甚么是副本桶演算法

那时我有另外一个罐子,这个罐子不必来塑料瓶,用来装副本:

带你了解什么是限流

副本会一定的速度扔进罐子里边,比如说我1秒扔10个副本进罐子:

带你了解什么是限流

罐子能装副本的个数有下限的,比如说我的罐子最多根本无法装1000个副本。

每个允诺进来,就会去罐子拿一个副本

比如说这秒我有1001个允诺,我就去罐子里头拿1001个副本,此时可能会出现三种情况:罐子里头没有1001个副本,只有1000个,那没拿到副本的允诺根本无法被阻塞了(等候)罐子里头有1001个副本,所有允诺都能执行。
带你了解什么是限流

副本桶演算法支持网络上的突发网络流量

漏桶和副本桶的区别:从上面的例子估计大家也能看出了,漏桶根本无法以一般来说的速度去处置允诺,而副本桶能以罐子最大的副本数去处置允诺

二、RateLimiter使用

RateLimiter是Guava的一个开闭组件,我这边的系统就管用到这个开闭组件,使用起来十分方便。

引入pom依赖:

<dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>20.0</version> </dependency>

RateLimiter它是基于副本桶演算法的,API非常简单,看以下的Demo:

public static void main(String[] args) { //线程池 ExecutorService exec = Executors.newCachedThreadPool(); //速度是每秒只有3个许可 final RateLimiter rateLimiter = RateLimiter.create(3.0); for (int i = 0; i < 100; i++) { final int no = i; Runnable runnable = new Runnable() { @Override public void run() { try { rateLimiter.acquire(); System.out.println(“Accessing: “ + no + “,time:” + new SimpleDateFormat(“yy-MM-dd HH:mm:ss”).format(new Date())); } catch (Exception e) { e.printStackTrace(); } } }; //执行线程 exec.execute(runnable); } //退出线程池 exec.shutdown(); }

他们能从结果看出,每秒根本无法执行三个:

带你了解什么是限流

三、分布式开闭

RateLimiter是一个单机的开闭组件,假如是分布式应用的话,该怎么做?

能使用Redis+Lua的方式来实现,大致的lua脚本标识符如下:

local key = “rate.limit:” .. KEYS[1] –开闭KEY local limit = tonumber(ARGV[1]) –开闭大小不一 local current = tonumber(redis.call(get, key) or “0”) if current + 1 > limit then –假如远远少于开闭大小不一 return 0 else –允诺数+1,并设置1秒过期 redis.call(“INCRBY”, key,“1”) redis.call(“expire”, key,“1”) return current + 1 end

Java标识符如下:

public static boolean accquire() throws IOException, URISyntaxException { Jedis jedis = new Jedis(“127.0.0.1”); File luaFile = new File(RedisLimitRateWithLUA.class.getResource(“/”).toURI().getPath() + “limit.lua”); String luaScript = FileUtils.readFileToString(luaFile); String key = “ip:” + System.currentTimeMillis()/1000; // 当前秒 String limit = “5”; // 最大限制 List<String> keys = new ArrayList<String>(); keys.add(key); List<String> args = new ArrayList<String>(); args.add(limit); Long result = (Long)(jedis.eval(luaScript, keys, args)); // 执行lua脚本,传入参数 return result == 1; }

解释:

Java标识符传入key和最大的限制limit参数进lua脚本执行lua脚本(lua脚本判断当前key是否少于了最大限制limit)假如少于,则返回0(开闭)假如没少于,返回1(程序继续执行)https://segmentfault.com/a/1190000016552464

更多资料参考:

https://segmentfault.com/a/1190000016042927[http://wuwenliang.net/2018/10/27/%E8%87%AA%E5%B7%B1%E5%86%99%E5%88%86%E5%B8%83%E5%BC%8F%E9%99%90%E6%B5%81%E7%BB%84%E4%BB%B6-%E5%9F%BA%E4%BA%8ERedis%E7%9A%84RateLimter/](http://wuwenliang.net/2018/10/27/自己写分布式开闭组件-基于Redis的RateLimter/)

最近一直在连载《对线面试官》系列,目前已经连载25篇啦!一个说人话的系列!

对线面试官】Java注解【对线面试官】Java泛型【对线面试官】 Java NIO【对线面试官】Java反射 && 动态代理【对线面试官】多线程基础【对线面试官】 CAS【对线面试官】synchronized【对线面试官】AQS&&ReentrantLock【对线面试官】线程池【对线面试官】ThreadLocal【对线面试官】CountDownLatch和CyclicBarrier【对线面试官】为甚么需要Java内存模型?【对线面试官】List【对线面试官】Map【对线面试官】SpringMVC【对线面试官】Spring基础【对线面试官】SpringBean生命周期【对线面试官】Redis基础【对线面试官】Redis持久化【对线面试官】Kafka基础【对线面试官】使用Kafka会考虑甚么问题?【对线面试官】MySQL索引【对线面试官】MySQL 事务&&锁机制&&MVCC【对线面试官】MySQL调优

【大厂面试知识点】、【简历模板】、【原创文章】电子书,共有1263页

我把这些上传到网盘,你们有需要间接下载就好了。做到这份上了,不会还想白嫖吧?点赞和转发又不必钱。

带你了解什么是限流

链接:pan.baidu.com/s/1pQTuKBYs… 密码:3wom

收藏等于白嫖,点赞才是真情!

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务