使用RateLimiter实现令牌桶算法

流量整形

流量整形(traffic shaping)典型作用是限制流出某一网络的某一连接的流量与突发,使这类报文以比较均匀的速度向外发送。流量整形通常使用缓冲区和令牌桶来完成,当报文的发送速度过快时,首先在缓冲区进行缓存,在令牌桶的控制下再均匀地发送这些被缓冲的文。

流量整形的核心算法有以下两种,具体采用的技术为GTS(Generic Traffic Shaping),通用流量整形:

漏桶算法(Leaky Bucket)

漏桶算法是网络世界中流量整形(Traffic Shaping)或速率限制(Rate Limiting)时经常使用的一种算法,它的主要目的是控制数据注入到网络的速率,平滑网络上的突发流量。漏桶算法提供了一种机制,通过它,突发流量可以被整形以便为网络提供一个稳定的流量。

令牌桶算法(Token Bucket)

有时人们将漏桶算法与令牌桶算法错误地混淆在一起。而实际上,这两种算法具有截然不同的特性并且为截然不同的目的而使用。它们之间最主要的差别在于:漏桶算法能够强行限制数据的传输速率,而令牌桶算法能够在限制数据的平均传输速率的同时还允许某种程度的突发传输。

令牌桶算法是网络流量整形(Traffic Shaping)和速率限制(Rate Limiting)中最常使用的一种算法。典型情况下,令牌桶算法用来控制发送到网络上的数据的数目,并允许突发数据的发送。

令牌桶这种控制机制基于令牌桶中是否存在令牌来指示什么时候可以发送流量。令牌桶中的每一个令牌都代表一个字节。如果令牌桶中存在令牌,则允许发送流量;而如果令牌桶中不存在令牌,则不允许发送流量。因此,如果突发门限被合理地配置并且令牌桶中有足够的令牌,那么流量就可以以峰值速率发送。

RateLimiter

RateLimiter是Guava的concurrent包下的一个用于限制访问频率的类.

package com.taikang.ratelimiter.demo;

import java.util.concurrent.Executors;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
import com.google.common.util.concurrent.RateLimiter;

public class RateLimiterTest {
    public static void main(String[] args) {
        testRateLimiter();
    }

    /**
     * RateLimiter类似于JDK的信号量Semphore,他用来限制对资源并发访问的线程数
     */
    public static void testRateLimiter() {
        
        ListeningExecutorService executorService = MoreExecutors
                .listeningDecorator(Executors.newFixedThreadPool(5));

        RateLimiter limiter = RateLimiter.create(2); // 每秒不超过4个任务被提交

        
        for (int i = 0; i < 50; i++) {
            limiter.acquire(); // 请求RateLimiter, 超过permits会被阻塞
            
            executorService.submit(new Task3("is "+ i));
        }
    }
}

class Task3 implements Runnable{
    String str;
    public Task3(String str){
        this.str = str;
    }
    @Override
    public void run() {
        System.out.println("Task2 call execute.." + str);
    }

}

你可能感兴趣的:(使用RateLimiter实现令牌桶算法)