前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring Boot 集成RateLimiter限流

Spring Boot 集成RateLimiter限流

原创
作者头像
HLee
修改2021-09-09 14:33:02
6930
修改2021-09-09 14:33:02
举报
文章被收录于专栏:房东的猫房东的猫房东的猫

RateLimiter 限流

RateLimiter 是基于令牌桶实现的限速。

匀速执行

import com.google.common.util.concurrent.RateLimiter;

import java.time.LocalTime;

public class RateLimiterTest {

    public static void main(String[] args) {
        RateLimiter rateLimiter = RateLimiter.create(5);
        for (int i=0; i< 10; i++) {
            rateLimiter.acquire();
            System.out.println(LocalTime.now());
        }
    }

}

运行结果:
10:23:53.612
10:23:53.741
10:23:53.940
10:23:54.137
10:23:54.335
10:23:54.538
10:23:54.737
10:23:54.935
10:23:55.135
10:23:55.339

可以看到,基本是相隔200ms打印一次时间。

acquire 方法会返回秒级的耗时:

import com.google.common.util.concurrent.RateLimiter;

public class RateLimiterTest {

    public static void main(String[] args) {
        RateLimiter rateLimiter = RateLimiter.create(5);
        for (int i=0; i< 10; i++) {
            double timeCost = rateLimiter.acquire();
            System.out.println("获取令牌耗时(单位秒): " + timeCost);
        }
    }

}

运行结果:
获取令牌耗时(单位秒): 0.0
获取令牌耗时(单位秒): 0.198251
获取令牌耗时(单位秒): 0.197075
获取令牌耗时(单位秒): 0.195677
获取令牌耗时(单位秒): 0.19635
获取令牌耗时(单位秒): 0.196841
获取令牌耗时(单位秒): 0.195845
获取令牌耗时(单位秒): 0.194625
获取令牌耗时(单位秒): 0.199044
获取令牌耗时(单位秒): 0.1966

突发流量

import com.google.common.util.concurrent.RateLimiter;
import com.google.common.util.concurrent.Uninterruptibles;

import java.util.concurrent.TimeUnit;

public class RateLimiterTest {

    public static void main(String[] args) {
        RateLimiter rateLimiter = RateLimiter.create(5);
        System.out.println("sleep 5秒");
        Uninterruptibles.sleepUninterruptibly(5, TimeUnit.SECONDS);
        for (int i=0; i< 10; i++) {
            double timeCost = rateLimiter.acquire();
            System.out.println("获取令牌耗时(单位秒): " + timeCost);
        }
    }

}

运行结果:
获取令牌耗时(单位秒): 0.0
获取令牌耗时(单位秒): 0.0
获取令牌耗时(单位秒): 0.0
获取令牌耗时(单位秒): 0.0
获取令牌耗时(单位秒): 0.0
获取令牌耗时(单位秒): 0.0
获取令牌耗时(单位秒): 0.196621
获取令牌耗时(单位秒): 0.197801
获取令牌耗时(单位秒): 0.199491
获取令牌耗时(单位秒): 0.200235

RateLimiter.create(5) 指定每秒匀速产生 5 个令牌,且令牌桶中最多5个令牌。

示例代码中获取的前5个令牌是之前颁发的已经在令牌桶中的令牌,所以获取的很快,几乎是同一时间旧全部拿出了。

预热限速

import com.google.common.util.concurrent.RateLimiter;

import java.util.concurrent.TimeUnit;

public class RateLimiterTest {

    public static void main(String[] args) {

        RateLimiter rateLimiter = RateLimiter.create(2, 3, TimeUnit.SECONDS);
        for (int i=0; i< 10; i++) {
            double timeCost = rateLimiter.acquire();
            System.out.println("获取令牌耗时(单位秒): " + timeCost);
        }
    }
}

运行结果:
获取令牌耗时(单位秒): 0.0
获取令牌耗时(单位秒): 1.331039
获取令牌耗时(单位秒): 0.996633
获取令牌耗时(单位秒): 0.664236
获取令牌耗时(单位秒): 0.496114
获取令牌耗时(单位秒): 0.496574
获取令牌耗时(单位秒): 0.498551
获取令牌耗时(单位秒): 0.49505
获取令牌耗时(单位秒): 0.498739
获取令牌耗时(单位秒): 0.499335

可以看到,耗时是逐步减少到500ms左右。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • RateLimiter 限流
    • 匀速执行
      • 突发流量
        • 预热限速
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档