1. 1 不可撤销
  2. 2 小年兽 程嘉敏
  3. 3 手放开 李圣杰
  4. 4 迷人的危险3(翻自 dance flow) FAFA
  5. 5 山楂树之恋 程佳佳
  6. 6 summertime cinnamons / evening cinema
  7. 7 不谓侠(Cover 萧忆情Alex) CRITTY
  8. 8 神武醉相思(翻自 优我女团) 双笙
  9. 9 空山新雨后 音阙诗听 / 锦零
  10. 10 Wonderful U (Demo Version) AGA
  11. 11 广寒宫 丸子呦
  12. 12 陪我看日出 回音哥
  13. 13 春夏秋冬的你 王宇良
  14. 14 世界が终わるまでは… WANDS
  15. 15 多想在平庸的生活拥抱你 隔壁老樊
  16. 16 千禧 徐秉龙
  17. 17 我的一个道姑朋友 双笙
  18. 18 大鱼  (Cover 周深) 双笙
  19. 19 霜雪千年(Cover 洛天依 / 乐正绫) 双笙 / 封茗囧菌
  20. 20 云烟成雨(翻自 房东的猫) 周玥
  21. 21 情深深雨濛濛 杨胖雨
  22. 22 Five Hundred Miles Justin Timberlake / Carey Mulligan / Stark Sands
  23. 23 斑马斑马 房东的猫
  24. 24 See You Again Wiz Khalifa / Charlie Puth
  25. 25 Faded Alan Walker / Iselin Solheim
  26. 26 Natural J.Fla
  27. 27 New Soul Vox Angeli
  28. 28 ハレハレヤ(朗朗晴天)(翻自 v flower) 猫瑾
  29. 29 像鱼 王贰浪
  30. 30 Bye Bye Bye Lovestoned
  31. 31 Blame You 眠 / Lopu$
  32. 32 Believer J.Fla
  33. 33 书信 戴羽彤
  34. 34 柴 鱼 の c a l l i n g【已售】 幸子小姐拜托了
  35. 35 夜空中最亮的星(翻自 逃跑计划) 戴羽彤
  36. 36 慢慢喜欢你 LIve版(翻自 莫文蔚) 戴羽彤
  37. 37 病变(翻自 cubi) 戴羽彤
  38. 38 那女孩对我说 (完整版) Uu
  39. 39 绿色 陈雪凝
  40. 40 月牙湾 LIve版(翻自 F.I.R.) 戴羽彤
夜空中最亮的星(翻自 逃跑计划) - 戴羽彤
00:00 / 04:10

夜空中最亮的星 能否听清

那仰望的人 心底的孤独和叹息

夜空中最亮的星 能否记起

那曾与我同行 消失在风里的身影

我祈祷拥有一颗透明的心灵

和会流泪的眼睛

给我再去相信的勇气

越过谎言去拥抱你

每当我找不到存在的意义

每当我迷失在黑夜里

噢喔喔 夜空中最亮的星

请指引我靠近你

夜空中最亮的星 是否知道

那曾与我同行的身影 如今在哪里

夜空中最亮的星 是否在意

是等太阳先升起 还是意外先来临

我宁愿所有痛苦都留在心底

也不愿忘记你的眼睛

哦 给我再去相信的勇气

哦 越过谎言去拥抱你

每当我找不到存在的意义

每当我迷失在黑夜里

噢喔喔 夜空中最亮的星

请照亮我向前行 哒~

我祈祷拥有一颗透明的心灵

和会流泪的眼睛 哦

给我再去相信的勇气

哦 越过谎言去拥抱你

每当我找不到存在的意义

每当我迷失在黑夜里

噢喔喔 夜空中最亮的星

请照亮我向前行

Google限速神器——RateLimiter分享

前言

对微服务有所涉猎的小伙伴,应该都知道限流组件这个东西,它是微服务领域中有一个特别重要的组件,它的作用是限制同一时间点访问某一个服务的线程的数量或者请求数,而且这样的场景在现实应用开发中使用的也别广泛,比如双十一秒杀、春运抢票。

如果没有这个组件的加持,那么我们的服务器很容易因为瞬时并发数量过高而导致宕机,所以换句话说,一个系统运行是否稳定,限流组件起着特别重要的作用的,所以从今天开始,我打算搜集下常用的限流解决方案,逐一研究下其基本原理,当然以我现阶段的积累,可能不会涉及太深。

今天我们就来看下googlgguava中提供的一款限流组件——RateLimiter,关于guava这个工具包,我们之前已经分享过其中集合部分的应用,感兴趣的小伙伴可以去看下:

https://mp.weixin.qq.com/s?__biz=MjM5NDMwNzA0NQ==&mid=2648417486&idx=1&sn=eb5aeaa688345cd64e3b77e527e95901&chksm=bea6ca4489d14352265b659325965918ad148ef932ad60af0baeaa85525afea0d2d31a2e0539&token=643197278&lang=zh_CN#rd

其实关于限流组件这块,我们当时在分享多线程相关内容的时候,有一个多线程组件就可以用来做限速使用,不知道给位小伙伴是否还记得——Semaphore,如果你还记得名字,说明你多线程这块学的还是比较扎实的,忘记了也没关系,好好复习下就好。

另外,因为Semaphore之前已经分享过了,所以今天就不再赘述了,感兴趣的小伙伴自己可以去看下:

https://mp.weixin.qq.com/s?__biz=MjM5NDMwNzA0NQ==&mid=2648419288&idx=1&sn=e893e3ee0877070fe541ce3add98781a&chksm=bea6c55289d14c44b11d27ac99a3c19d0ca1ba12bad8ecaf4671200e7d743f896a477da69195&token=643197278&lang=zh_CN#rd

RateLimiter

我们先看下官方文档对于RateLimiter的描述:

RateLimiter经常用于限制对一些物理资源或者逻辑资源的访问速率。与Semaphore 相比,Semaphore 限制了并发访问的数量而不是使用速率。

通过设置许可证的速率来定义RateLimiter。在默认配置下,许可证会在固定的速率下被分配,速率单位是每秒多少个许可证。为了确保维护配置的速率,许可会被平稳地分配,许可之间的延迟会做调整。

可能存在配置一个拥有预热期的RateLimiter 的情况,在这段时间内,每秒分配的许可数会稳定地增长直到达到稳定的速率。

从概念上讲,速率限制器(RateLimiter)以可配置的速率分发许可证。 如有必要,每个acquire() 都会阻塞,直到获得许可为止,然后获取它。 获得许可后,无需发放许可证。

RateLimiter 对于并发使用是安全的:它将限制来自所有线程的总调用率。 但请注意,它并不能保证公平。

源码简单分析

从源码来看,RateLimiter是一个抽象类,而且它并没有直接对外提供构造方法,所以我们只能通过静态方法create来创建RateLimiter的实例:

另外,从源码中发现,这个组件的使用环境必须大于等于jdk13,所以各位小伙伴在测试的时候一定要注意:

根据这段代码,以及我们的多线程使用经验来说,这个方法本身是组赛的,而且阻塞是基于stopwatch来实现的,而且这里阻塞的时长是根据我们的速率计算的,关于速率我们等下会说到。

简单使用

其实关于RateLimter的使用,在源码的注释中,官方已经给出了相应的示例:

第一的示例的作用是,限制线程的执行速率,也就是每秒执行不能超过两次。下面我们通过简单的代码演示下这个示例,然后从实例中体会RateLimiter的应用场景。

代码实现很简单,我们通过线程池提交了100个打印操作,然后在线程启动前,我们加了一行代码:

rateLimiter.acquire()

这行代码的作用就是控制速率,这个方法就更过分了,它需要jdk16以上才能运行,我这里刚好是1613的版本返回值是void:

根据这段代码,以及我们的多线程使用经验来说,这个方法本身是组赛的,而且阻塞是基于stopwatch来实现的,而且这里阻塞的时长是根据我们的速率计算的,关于速率我们等下会说到。

下面是示例的完整实现:

public class RateLimiterTest {
    public static void main(String[] args) {
        final RateLimiter rateLimiter = RateLimiter.create(2.0);
        ExecutorService executorService = Executors.newFixedThreadPool(100);
        List<Runnable> tasks = Lists.newArrayList();
        for (int i = 0; i < 100; i++) {
            rateLimiter.acquire();
            executorService.execute(() -> {
                String dateTime = new SimpleDateFormat("HH:mm:ss:SSS").format(new Date());
                System.out.printf("limiter-%s%n", dateTime);
            });
        }
        executorService.shutdown();
    }
}

运行结果如下:

从运行结果可以看出来,不论运行多少次,每一秒始终只会运行两次,而且两次的间隔时间刚好是500ms,这说明时间间隔的算法是1000ms / 22就是我们上面指定的速率),我们可以测试下:

当我们将速率设置为4时,线程之间间隔的时间接近250ms,说明我们上面的推断基本正确,但是速率的具体控制算法还需要进一步研究源码。

结语

鉴于时间的关系,RateLimiter先将这么多,这里算是引入RateLimiter的限流解决方案,希望借此能够勾起各位小伙伴对于限流组件实现原理的思考。

从实际应用角度来看,RateLimiter似乎还不具备实际业务应用的条件,一个是因为它的运行环境要求比较高,必须jdk 16及以上,现阶段应该很少有企业在正式环境使用这个版本;另一个原因是,RateLimiter的类和部分方法上加了@Bate这样的注解,表明它应该还是一款正处于开发测试阶段的产品,尚未经过相关论证,应用到先说环境确实也需要谨慎验证。

但是如果作为学习借鉴的话,那RateLimiter无疑是比较完美的实验品,从个人的角度来说,我觉得RateLimiter的源码值得研究,而且我后期还会进一步探究它的实现原理。好了,今天就先到这里吧,各位小伙伴晚安呀!

posted @ 2021-11-01 00:03  云中志  阅读(566)  评论(0编辑  收藏  举报