我的编程空间,编程开发者的网络收藏夹
学习永远不晚

SpringBoot怎么使用RateLimiter通过AOP方式进行限流

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

SpringBoot怎么使用RateLimiter通过AOP方式进行限流

这篇文章主要讲解了“SpringBoot怎么使用RateLimiter通过AOP方式进行限流”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“SpringBoot怎么使用RateLimiter通过AOP方式进行限流”吧!

使用RateLimiter通过AOP方式进行限流

1、引入依赖

<!-- guava 限流 --><dependency>     <groupId>com.google.guava</groupId>     <artifactId>guava</artifactId>     <version>25.1-jre</version></dependency>

2、自定义注解

@Target({ElementType.PARAMETER, ElementType.METHOD})    @Retention(RetentionPolicy.RUNTIME)    @Documented    public  @interface ServiceLimit {      String description()  default "";}

3、AOP实现类

@Component@Scope@Aspectpublic class LimitAspect {    每秒只发出5个令牌,此处是单进程服务的限流,内部采用令牌捅算法实现    private static   RateLimiter rateLimiter = RateLimiter.create(5.0);        //Service层切点  限流    @Pointcut("@annotation(com.itstyle.seckill.common.aop.ServiceLimit)")      public void ServiceAspect() {            }        @Around("ServiceAspect()")    public  Object around(ProceedingJoinPoint joinPoint) {         Boolean flag = rateLimiter.tryAcquire();        Object obj = null;        try {            if(flag){                obj = joinPoint.proceed();            }        } catch (Throwable e) {            e.printStackTrace();        }         return obj;    } }

4、使用

@Override@ServiceLimit@Transactional    public Result startSeckil(long seckillId,long userId) {        //todo 操作    }

SpringBoot之限流

限流的基础算法

令牌桶和漏桶

  • 漏桶算法 的实现往往依赖于队列,请求到达如果队列未满则直接放入队列,然后有一个处理器按照固定频率从队列头取出请求进行处理。如果请求量大,则会导致队列满,那么新来的请求就会被抛弃。

  • 令牌桶算法 则是一个存放固定容量令牌的桶,按照固定速率往桶里添加令牌。桶中存放的令牌数有最大上限,超出之后就被丢弃或者拒绝。当流量或者网络请求到达时,每个请求都要获取一个令牌,如果能够获取到,则直接处理,并且令牌桶删除一个令牌。如果获取不到,该请求就要被限流,要么直接丢弃,要么在缓冲区等待。

令牌桶和漏桶对比

  • 令牌桶是按照固定速率往桶中添加令牌,请求是否被处理需要看桶中令牌是否足够,当令牌数减为零时则拒绝新的请求;漏桶则是按照常量固定速率流出请求,流入请求速率任意,当流入的请求数累积到漏桶容量时,则新流入的请求被拒绝;

  • 令牌桶限制的是平均流入速率,允许突发请求,只要有令牌就可以处理,支持一次拿3个令牌,4个令牌;漏桶限制的是常量流出速率,即流出速率是一个固定常量值,比如都是1的速率流出,而不能一次是1,下次又是2,从而平滑突发流入速率;

  • 令牌桶允许一定程度的突发,而漏桶主要目的是平滑流出速率;

Guava RateLimiter

依赖

<dependency>    <groupId>com.google.guava</groupId>    <artifactId>guava</artifactId>    <version>28.1-jre</version>    <optional>true</optional></dependency>

2.示例代码 

@Slf4j@Configurationpublic class RequestInterceptor implements HandlerInterceptor {    // 根据字符串分不同的令牌桶, 每天自动清理缓存    private static LoadingCache<String, RateLimiter> cachesRateLimiter = CacheBuilder.newBuilder()            .maximumSize(1000)  //设置缓存个数                        .expireAfterAccess(1, TimeUnit.HOURS)            .build(new CacheLoader<String, RateLimiter>() {                @Override                public RateLimiter load(String key) throws Exception {                    // 新的字符串初始化 (限流每秒2个令牌响应)                    return RateLimiter.create(2);                }            });    @Override    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)            throws Exception {        log.info("request请求地址path[{}] uri[{}]", request.getServletPath(), request.getRequestURI());        try {            String str = "hello";            // 令牌桶            RateLimiter rateLimiter = cachesRateLimiter.get(str);            if (!rateLimiter.tryAcquire()) {                System.out.println("too many requests.");                return false;            }        } catch (Exception e) {            // 解决拦截器的异常,全局异常处理器捕获不到的问题            request.setAttribute("exception", e);            request.getRequestDispatcher("/error").forward(request, response);        }        return true;    }}

3.测试

@RestController@RequestMapping(value = "user")public class UserController {    @GetMapping    public Result test2(){        System.out.println("1111");        return new Result(true,200,"");    }}

http://localhost:8080/user/

如果没有result类,自己可以随便返回个字符串

4.测试结果

SpringBoot怎么使用RateLimiter通过AOP方式进行限流

其他

创建

RateLimiter提供了两个工厂方法:

一个是平滑突发限流

RateLimiter r = RateLimiter.create(5); //项目启动,直接允许5个令牌

一个是平滑预热限流

RateLimiter r = RateLimiter.create(2, 3, TimeUnit.SECONDS); //项目启动后3秒后才会到达设置的2个令牌

缺点

RateLimiter只能用于单机的限流,如果想要集群限流,则需要引入redis或者阿里开源的sentinel中间件。

TimeUnit.SECONDS);` //项目启动后3秒后才会到达设置的2个令牌

感谢各位的阅读,以上就是“SpringBoot怎么使用RateLimiter通过AOP方式进行限流”的内容了,经过本文的学习后,相信大家对SpringBoot怎么使用RateLimiter通过AOP方式进行限流这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程网,小编将为大家推送更多相关知识点的文章,欢迎关注!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

SpringBoot怎么使用RateLimiter通过AOP方式进行限流

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

SpringBoot怎么使用RateLimiter通过AOP方式进行限流

这篇文章主要讲解了“SpringBoot怎么使用RateLimiter通过AOP方式进行限流”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“SpringBoot怎么使用RateLimiter通
2023-07-02

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录