公司最近在推一个限流工具接入,提供的功能有单机限流、集群限流等。想了解一下限流的原理和设计,看了一下wiki里面有提到用了guava的ratelimiter工具,查了一些资料了解了一下
主要的限流算法有: 漏斗算法和令牌桶算法
漏斗算法: 往漏斗里面放请求,我的理解漏斗就是一个变量或者集合。在以固定的速率去消费这些请求,如果请求超过了漏斗的容量,就溢出,即被限流
令牌桶算法: 以一定的速度向一个桶(一个变量或者其他设计)放令牌(变量加1)。请求来了,去桶里获取令牌,如果获取到,就执行。没有获取到,阻塞,看源码,应该是sleep了一段时间
写了一个demo, 很简单
guava maven依赖
<dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>27.0-jre</version> </dependency>
RateLimiter.java
import com.google.common.util.concurrent.RateLimiter; /** * @Author: <guanxianseng@163.com> * @Description: * @Date: Created in : 2018/11/4 3:02 PM **/ public class RateLimiterDemo { public static void main(String[] args) { testWithRateLimiter(); } public static void testWithRateLimiter() { RateLimiter limiter = RateLimiter.create(1.0); // 每秒不超过1个任务被提交 for (int i = 0; i < 1000; i++) { double timeWaited = limiter.acquire(); // 请求RateLimiter, 超过permits会被阻塞 System.out.println("time waited: " + timeWaited); } } }
备注: 这里被限流的请求可能会一直被hold住,如果想立刻返回可以使用tryAcquire()这个guava api
后面还需要查资料,看下源码
1. 怎么放令牌的
2. 怎么取令牌的
3. sleep的时间怎么计算的