美文网首页Java实战技术Java学习笔记
Google出品的限流术RateLimiter

Google出品的限流术RateLimiter

作者: JavaQ | 来源:发表于2017-07-07 21:57 被阅读232次

    限流
    通过对某一时间窗口内的请求数进行限制,保持系统的可用性和稳定性,防止因流量暴增而导致的系统运行缓慢或宕机。常用的限流算法有令牌桶和和漏桶,而Google开源项目Guava中的RateLimiter使用的就是令牌桶控制算法。

    令牌桶算法
    有一个固定容量用于存储令牌的桶,按照设定的频率向桶中放入令牌,过程如下图所示。


    Image.jpg

    过程描述如下:
    1.如果设定每秒向桶中放入5个令牌,则将会以每200毫秒的固定速率向桶中放入一个令牌;
    2.桶中最多存放n个令牌,如果桶满了,则新放入的令牌将会被丢弃;
    3.当一个m字节的数据包到达时,将会使用m个令牌,然后将该数据包发出;
    4.如果桶中可用令牌数小于k,则该数据包将需要等待或丢弃。

    RateLimiter
    RateLimiter实现的令牌桶算法,不仅可以应对正常流量的限速,而且可以处理突发暴增的请求,实现平滑限流。RateLimiter方法摘要如下。

    1.png 2.png

    应用
    场景:向第三方服务发送多笔查询请求,如果是单线程发送请求,效率很慢;如果使用多线程发送,第三方服务处理能力有限,直接返回失败。
    解决:使用RateLimiter限制发送请求的频率,假设第三方服务每秒可处理5笔请求,示例代码如下

            List<String> queryNos = newArrayList("1", "2", "3", "4", "5", "6", "7");
            RateLimiter limiter = RateLimiter.create(5);
            ExecutorService executorService = Executors.newFixedThreadPool(5);
            for (final String queryNo : queryNos) {
                limiter.acquire();
                executorService.submit(new Runnable() {
                    public void run() {
                        //...发送请求
                        System.out.println(queryNo + ":" + Calendar.getInstance().getTimeInMillis());
                    }
                });
            }
    

    结果输出如下:
    1:1499333845323
    2:1499333845505
    3:1499333845704
    4:1499333845904
    5:1499333846105
    6:1499333846304
    7:1499333846504
    可以看到每个请求间隔差不多200毫秒,实现了限流。

    相关文章

      网友评论

        本文标题:Google出品的限流术RateLimiter

        本文链接:https://www.haomeiwen.com/subject/opbrhxtx.html