当前位置:

首页 > 编程开发 > SpringBoot怎么使用RateLimiter通过AOP方式进行限流

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

使用RateLimiter通过AOP方式进行限流1、引入依赖com.google.guavaguava25.1-jre2、自定义注解@Target({ElementType.PARAMETER,ElementType.METHOD})@Retention(RetentionPolicy.RUNTIME)@Documentedpublic@interfaceServiceLimit{Stringdescription()default"";}3、AOP实现类@Component@Scope@Aspectpu

本文目录

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

    1、引入依赖

    
    
         com.google.guava
         guava
         25.1-jre
    

    2、自定义注解

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

    3、AOP实现类

    @Component
    @Scope
    @Aspect
    public 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

    1.依赖

    
        com.google.guava
        guava
        28.1-jre
        true
    

    2.示例代码 

    @Slf4j
    @Configuration
    public class RequestInterceptor implements HandlerInterceptor {
        // 根据字符串分不同的令牌桶, 每天自动清理缓存
        private static LoadingCache cachesRateLimiter = CacheBuilder.newBuilder()
                .maximumSize(1000)  //设置缓存个数
                /**
                 * expireAfterWrite是在指定项在一定时间内没有创建/覆盖时,会移除该key,下次取的时候从loading中取
                 * expireAfterAccess是指定项在一定时间内没有读写,会移除该key,下次取的时候从loading中取
                 * refreshAfterWrite是在指定时间内没有被创建/覆盖,则指定时间过后,再次访问时,会去刷新该缓存,在新值没有到来之前,始终返回旧值
                 * 跟expire的区别是,指定时间过后,expire是remove该key,下次访问是同步去获取返回新值;
                 * 而refresh则是指定时间后,不会remove该key,下次访问会触发刷新,新值没有回来时返回旧值
                 */
                .expireAfterAccess(1, TimeUnit.HOURS)
                .build(new CacheLoader() {
                    @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个令牌
    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
    作者最新文章
    编程开发
    相关文章 更多
    Java实现AOP日志记录配置与代码详解
    Java实现AOP日志记录配置与代码详解

    AOP日志记录通过将日志功能与业务逻辑解耦,使代码更清晰、维护更便捷。1.首先需引入SpringAOP和AspectJ依赖;2.定义切点(Pointcut)指定拦截方法;3.编写通知(Advice)处理日志逻辑,如@Before、@AfterReturning等;4.创建切面(Aspect)整合切点与通知,并标注@Aspect和@Component;5.启用AOP自动代理。敏感数据可通过脱敏、限制记录字段或调整日志级别来避免泄露。性能影响取决于日志复杂度,建议异步记录和优化操作。选择切点表达式时应结合方法

    Spring框架中 AOP(面向方面编程)是如何实现的?
    Spring框架中 AOP(面向方面编程)是如何实现的?

    SpringAOP基于Java动态代理来实现面向方面编程,允许在不修改原始代码情况下,在方法执行前后插入附加逻辑。具体步骤如下:创建代理对象,使用Proxy.newProxyInstance()方法,提供类加载器、接口和调用处理器。调用处理器的invoke()方法,获取目标对象、拦截器链,并依次调用拦截器invoke()。最后,如果没有异常,调用目标对象的方法。

    PHP中的面向切面编程(AOP)初探
    PHP中的面向切面编程(AOP)初探

    随着软件开发的不断发展,越来越多的编程语言和技术层出不穷。其中,PHP作为一门广泛应用于Web开发的脚本语言,在不断发展和革新的过程中,也涌现出了许多重要的概念和技术,如面向对象编程(OOP)、设计模式等,而今天我们要探讨的是PHP中的另一种编程方式——面向切面编程(AOP)。什么是AOP?AOP,全称是Aspect-OrientedProgramming

    springBoot项目常用目录有哪些
    springBoot项目常用目录有哪些

    springBoot项目常用目录springBoot项目的目录结构及名规范介绍基于SpringBoot开发时的目录结构及命名规范,通过介绍能够为你解决,在实际项目中如何规划目录结构?如何命名目录更规范?各个目录分别代表什么含义?等三个问题。目录说明servicex//项目名|-admin-ui//管理服务前端代码(一般将UI和SERVICE放到一个工程中,便于管理)|-servicex-auth//模块1|-servicex-common//模块2|-servicex-gateway//模块3|-serv

    探索Spring Boot架构:深入解析框架内部机制
    探索Spring Boot架构:深入解析框架内部机制

    SpringBoot的架构可以分为以下几个主要组件:Spring核心模块:springBoot的核心模块提供了Spring框架的基本功能,包括依赖注入、aop、事务管理等。这些模块是Spring应用程序的基础,为SpringBoot的开发提供了坚实的基础。SpringBootStarter:SpringBootStarter是一个预先配置好的依赖项集合,它可以帮助开发者快速构建Spring应用程序。SpringBootStarter提供了各种各样的依赖项,涵盖了各种常用的功能,如web开发、数据访问、安全

    解析SpringBoot和SpringMVC之间的异同
    解析SpringBoot和SpringMVC之间的异同

    解析SpringBoot和SpringMVC之间的异同SpringBoot和SpringMVC是Java领域中非常重要的开发框架。虽然它们都属于Spring框架的一部分,但是在使用和功能上有一些明显的区别。本文将对SpringBoot和SpringMVC进行比较,解析它们之间的异同。首先,让我们来了解一下SpringBoot。SpringBo

    深入了解Spring中AOP的典型应用方式
    深入了解Spring中AOP的典型应用方式

    探索Spring中AOP的常见应用方式概述:随着软件开发的不断发展,业务逻辑的复杂性也日益增加。为了提高代码的可维护性和重用性,以及实现切面关注点的分离,面向切面编程(AOP)的概念被引入到软件开发中。Spring框架是Java开发中广泛应用的框架之一,也提供了强大的AOP支持。本文将探索Spring中AOP的常见应用方式,并提供具体的代码示例。一、前置通知

    解析Spring AOP的常见应用场景
    解析Spring AOP的常见应用场景

    Spring中AOP的常见应用方式解析引言:在软件开发过程中,面向切面编程(AOP)是一种很重要的技术,它能够通过在程序运行期间动态地将特定的代码片段织入到目标方法中,提供额外的功能和扩展。而Spring作为一个强大的开发框架,提供了丰富的AOP支持,本文将详细介绍Spring中AOP的常见应用方式,包括声明式和编程式两种方式,并提供具体的代码示例。一、声明

    探索SpringCloud和SpringBoot在微服务领域的不同应用方式
    探索SpringCloud和SpringBoot在微服务领域的不同应用方式

    近年来,随着云计算和分布式架构的兴起,微服务架构的应用越来越广泛。而SpringCloud和SpringBoot作为Java开发中的两个重要框架,对于微服务的实现起到了重要的作用。然而,很多人对于它们在微服务领域的不同应用方式还存在一定的疑惑。本文将从不同的角度探索SpringCloud和SpringBoot在微服务中的应用方式。首先,我们来了解一下Spri

    SpringBoot和SpringMVC有何区别?
    SpringBoot和SpringMVC有何区别?

    SpringBoot与SpringMVC的不同之处在哪里?SpringBoot和SpringMVC是两个非常流行的Java开发框架,用于构建Web应用程序。尽管它们经常分别被使用,但它们之间的不同之处也是很明显的。首先,SpringBoot可以被看作是一个Spring框架的扩展或者增强版。它旨在简化Spring应用程序的初始化和配置过程,以帮助开发人

    查看更多
    精品专题 更多
    装机必备
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows
    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    PDF教程
    PDF教程

    正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

    Mac软件 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    Aperty macOS版
    Aperty macOS版
    macOS

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    WINDOWS 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    PixTV 网页版
    PixTV 网页版
    Windows

    PixTV 是一款在浏览器中使用的 AI 视觉内容创作平台,提供图片、视频、音频、文字生成、AI 分镜、局部重绘、提示词反推和无限画布等工具,适合短剧、漫剧、广告及社交媒体内容制作。