RateLimiter接口限流

在开发对外接口时,为了保证系统的安全性和可靠性,往往需要限制接口的调用频率,即1s允许调用的次数,使用guava的ratelimiter比较合适。对于限流一般的算法采用是:楼桶算法和令牌桶算法。

     1、漏桶算法

         漏桶(Leaky Bucket)算法思路很简单,水(请求)先进入到漏桶里,漏桶以一定的速度出水(接口有响应速率),当水流入速度过大会直接溢出(访问频率超过接口响应速率),然后就拒绝请求,可以看出漏桶算法能强行限制数据的传输速率.示意图如下:

   

         可见这里有两个变量,一个是桶的大小,支持流量突发增多时可以存多少的水(burst),另一个是水桶漏洞的大小(rate)。

         因为漏桶的漏出速率是固定的参数,所以,即使网络中不存在资源冲突(没有发生拥塞),漏桶算法也不能使流突发(burst)到端口速率.因此,漏桶算法对于存在突发特性的流量来说缺乏效率.

     2、令牌桶算法

         令牌桶算法(Token Bucket)和 Leaky Bucket 效果一样但方向相反的算法,更加容易理解.随着时间流逝,系统会按恒定1/QPS时间间隔(如果QPS=100,则间隔是10ms)往桶里加入Token(想象和漏洞漏水相反,有个水龙头在不断的加水),如果桶已经满了就不再加了.新请求来临时,会各自拿走一个Token,如果没有Token可拿了就阻塞或者拒绝服务.

 

  令牌桶的另外一个好处是可以方便的改变速度. 一旦需要提高速率,则按需提高放入桶中的令牌的速率. 一般会定时(比如100毫秒)往桶中增加一定数量的令牌, 有些变种算法则实时的计算应该增加的令牌的数量.

guave的ratelimiter采用的是令牌通的算法,假设1S需要限流5次;也就是1S会往桶里面方5个Token;如果在这1S内桶满了则不再加请求,如果空了则表示达到限制的上线了,会阻塞,知道有数据加入再次处理。

public class RateLimitTest {

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        testRateLimiter();
    }

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

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

        for (int i = 0; i < 10; i++) {
            limiter.acquire(); // 请求RateLimiter, 超过permits会被阻塞
            final ListenableFuture<Integer> listenableFuture = executorService.submit(new Task("is " + i + "--" + limiter.getRate()));

        }
    }
}

class Task implements Callable<Integer> {
    String str;

    public Task(String str) {
        this.str = str;
    }

    @Override
    public Integer call() throws Exception {
        System.out.println(System.currentTimeMillis() / 1000 + "---" + Thread.currentThread().getName() + "-call execute.." + str);
        TimeUnit.SECONDS.sleep(10);
        return 7;
    }
}

结果:

1493361377---pool-1-thread-1-call execute..is 0--3.0
1493361377---pool-1-thread-2-call execute..is 1--3.0

1493361378---pool-1-thread-3-call execute..is 2--3.0
1493361378---pool-1-thread-4-call execute..is 3--3.0
1493361378---pool-1-thread-5-call execute..is 4--3.0

1493361379---pool-1-thread-6-call execute..is 5--3.0
1493361379---pool-1-thread-7-call execute..is 6--3.0
1493361379---pool-1-thread-8-call execute..is 7--3.0

1493361380---pool-1-thread-9-call execute..is 8--3.0
1493361380---pool-1-thread-10-call execute..is 9--3.0

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值