Guava RateLimiter总结
1 , Guava在对RateLimiter设计中采用的是令牌桶的算法 , 提供了普通和预热两种模型 , 在存储令牌增加和消耗的设计思路是计算函数积分的方式 。
2 , 对于第一个新来的请求 , 无论请求多少令牌 , 不阻塞 。
3 , 内部使用线程sleep方式达到线程等待 , 没超时时间会一直等到有令牌
4 , 令牌存储发生在请求令牌时 , 不需要单独线程实现不断产生令牌的算法
5 , 内部设计的类一些参数并不开放外部配置
漏桶
原理如图:
文章插图
我们有一个固定的桶 , 这个桶的出水速率是固定的 , 流量不断往桶中放水 , 进水速度比出水速度快的时候 , 可以在桶中有一个缓冲 , 可是到达一定量超出桶的容量 , 就会溢出桶 , 无法接受新的请求 。
这个思路不就是阻塞队列嘛 , 只要在消费的放保持固定速率即可 。
实现类似如下代码(示意使用):
public class LeakyBucketLimiter { BlockingQueue<String> leakyBucket; long rate; public LeakyBucketLimiter(int capacity, long rate) { this.rate = rate; this.leakyBucket = new ArrayBlockingQueue<String>(capacity); } public boolean offer(){ return leakyBucket.offer(""); } class Consumer implements Runnable{ public void run() { try { while (true){ Thread.sleep(1000/rate); leakyBucket.take(); } } catch (InterruptedException e) {} } }}和令牌桶允许一定突发请求时的高速率 , 以及空闲后降低速率不同的是 , 漏桶算法是必然保证速率不变的 。
最后
- 限流必然带来性能损失 , 如何避免?
- 实际场景中是单机限流还是分布式限流?
- 拓展
本文并不是限流的全部 , 关于限流这里只聊到了相关的一些常规的算法 , 可以说是冰山一角 , 还有很多知识等待我们去探索 , 前路漫漫 。
另外 , 后续会参考开源限流方案 Sentinel 和 Bucket4j 进一步研究实践限流的落地方案 。
推荐阅读
- Java8新特性之空指针异常的克星Optional类
- 跟我一起了解Java到底好在哪?
- 交通事故现场拍照技巧,全是干货!
- 防火墙主备切换案例分析,干货值得收藏
- java服务 tomcat安装,不要太简单
- Java开发必会的Linux命令
- 常用排序算法之JavaScript实现
- Java核心技术-macOS下配置Java11环境
- 分享cmd 窗口中运行 Java 程序小技巧
- 如何理解JAVA类装载器ClassLoader?高级开发才懂的技术点