参考:
https://www.jianshu.com/p/5d4fe4b2a726
https://blog.csdn.net/charleslei/article/details/53152883
令牌桶算法的原理是系统会以一个恒定的速度往桶里放入令牌,而如果请求需要被处理,则需要先从桶里获取一个令牌,当桶里没有令牌可取时,则拒绝服务。
如果我们要以 1000 的 tps 完成某个数据同步任务。
例1:传输速度比 RateLimiter 设定 tps 快,通过 RateLimiter 降低传输 tps。 public static void main(String[] args) throws Exception { int[] messageCountList = new int[] {10000, 1000, 100}; // 1000 tps RateLimiter rateLimiter = RateLimiter.create(1000); for (int messageCount : messageCountList) { rateLimiter.acquire(messageCount); fastRun(messageCount); } } private static void fastRun(int messageCount) { SimpleDateFormat formatter = new SimpleDateFormat("dd-MMM-yyyy HH:mm:ss:SSS"); System.out.println("transfer start time : " + formatter.format(new Date())); System.out.println("transfered message count : " + messageCount); System.out.println("transfer end time : " + formatter.format(new Date())); } 输出: start time : 03-十一月-2019 00:08:41:497 transfer start time : 03-十一月-2019 00:08:41:515 transfered message count : 10000 transfer end time : 03-十一月-2019 00:08:41:515 transfer start time : 03-十一月-2019 00:08:51:520 transfered message count : 1000 transfer end time : 03-十一月-2019 00:08:51:520 transfer start time : 03-十一月-2019 00:08:52:519 transfered message count : 100 transfer end time : 03-十一月-2019 00:08:52:519 可见: 1. 第一次尽管需要 10000 个 permits,但仍然是立即就拿到了。 2. 第二次只需要 1000 个 permits,但需要补足第一次欠的 10000 个 permits,所以等了 10s。 3. 第三次补足第二次欠的 1000 个 permits,所以等了 1s。 4. 前后共耗时:11s。显然尽管消息传输很快,但总传输速度被降下来了。 5. 从上可知:获取 permits 时,是先获取,再补足的方式。 例2:传输速度比 RateLimiter 设定的 tps 慢。 private static void slowRun(int messageCount) throws Exception { Thread.sleep(messageCount * 2); SimpleDateFormat formatter = new SimpleDateFormat("dd-MMM-yyyy HH:mm:ss:SSS"); System.out.println("transfer start time : " + formatter.format(new Date())); System.out.println("transfered message count : " + messageCount); System.out.println("transfer end time : " + formatter.format(new Date())); } public static void main(String[] args) throws Exception { int[] messageCountList = new int[] {10000, 1000, 100}; // 1000 tps RateLimiter rateLimiter = RateLimiter.create(1000); for (int messageCount : messageCountList) { rateLimiter.acquire(messageCount); slowRun(messageCount); } } 输出: start time : 03-十一月-2019 00:06:43:688 transfer start time : 03-十一月-2019 00:06:43:704 transfered message count : 10000 transfer end time : 03-十一月-2019 00:07:03:707 transfer start time : 03-十一月-2019 00:07:03:707 transfered message count : 1000 transfer end time : 03-十一月-2019 00:07:05:709 transfer start time : 03-十一月-2019 00:07:05:709 transfered message count : 100 transfer end time : 03-十一月-2019 00:07:05:912 可见: 1. 第一次获取 10000 个 permits,仍然是立即就拿到了。 2. 第二次获取 1000 个 permits 时,由于第一次的 10000 条数据传输过慢,RateLimiter 已经累积了许多 permits,所以不需等待,直接获取了 1000 个 permits。 3. 总共耗时 22s,由于 RateLimiter 的 tps 比传输速度快,所以 RateLimter 并不会额外限流。