公司最近在推一個限流工具接入,提供的功能有單機限流、集群限流等。想了解一下限流的原理和設計,看了一下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的時間怎么計算的