SpringBoot中间件封装限流器的方案详解

 更新时间:2023年07月10日 17:09:02   作者:看表该更新博客了  
这篇文章主要介绍了SpringBoot中间件封装限流器,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

背景

通常能知道一个系统服务在正产增速下流量大小,扩容与压测也是基于此。若有突发或者恶意攻击访问,都要将流量拦截在外。这部分功能不属于业务侧,它是通用非业务的共性需求,所以我们将共性抽取为限流中间件。

方案设计

图解:

Ratelimiter

  • 谷歌Guava库中的一个限流工具类,用于限制访问限制某一资源,令牌桶思想的一个实现,可实现流量控制。

用到其两个方法:

  • create():创建一个RateLimiter实例,并设置该实例的限流速率(即允许每秒执行的任务数),例如:
RateLimiter rateLimiter = RateLimiter.create(10);

上述代码将创建一个每秒允许10个任务的RateLimiter实例。

tryAcquire():尝试获取一个许可,若获取成功则返回true,否则返回false。 例如:

if (rateLimiter.tryAcquire()) {
    // do something
}

上述代码将尝试获取一个许可,如果该实例当前拥有足够的许可,则执行do something操作

使用自定义注解和AOP,拦截需要被限流保护的方法。

拦截后,用Ratelimiter做限流处理

  • 使用自定义注解和AOP,拦截需要被限流保护的方法。
  • 拦截后,用Ratelimiter做限流处理

代码示例

1.自定义注解

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface DoRateLimiter {
    // 每秒访问次数限制
    public double rate() default 0d;
    // 超频后的触发熔断默认响应结果
    public String returnJson() default "";
}

2.常量类

public class Constant {
    /**
     * 全局Hashmap,用于存放【方法】对应的限流类
     * key: 类名 + 方法名
     * value: 对应限流类
     */
    public static Map<String, RateLimiter> stringRateLimiterMap = Collections.synchronizedMap(new HashMap<String, RateLimiter>());
}

3.切面逻辑处理

PS:切面中的实现细节/注解的使用已经在统一白名单中间件 文章中详细梳理过了,需要请移步

@Component
@Aspect
public class RateLimiterHandle {
    // 切点
    @Pointcut("@annotation(com.example.ratelimiteer.annotation.DoRateLimiter)")
    public void aopPointcut() {
    }
    /**
     * @param jp            切点
     * @param doRateLimiter 注解实例
     * @return 方法响应结果
     * @throws Throwable
     */
    @Around(value = "aopPointcut()&& @annotation(doRateLimiter)")
    public Object handle(ProceedingJoinPoint jp, DoRateLimiter doRateLimiter) throws Throwable {
        // 判断是否开启限流
        if (doRateLimiter.rate() == 0d) {
            return jp.proceed();
        }
        // 构建限流哈希Map的Key: 类名 + "." + "方法名"
        String className = jp.getTarget().getClass().getName();
        MethodSignature signature = (MethodSignature) jp.getSignature();
        Method method = jp.getTarget().getClass().getMethod(signature.getMethod().getName(), signature.getMethod().getParameterTypes());
        String methodName = method.getName();
        String key = className + "." + methodName;
        // 第一次走到该接口
        if (!Constant.stringRateLimiterMap.containsKey(key)) {
            Map<String, RateLimiter> rateLimiterMap = Constant.stringRateLimiterMap;
            rateLimiterMap.put(key, RateLimiter.create(doRateLimiter.rate()));
        }
        // 判断是否限流
        RateLimiter rateLimiter = Constant.stringRateLimiterMap.get(key);
        if (rateLimiter.tryAcquire()) {
            // 未超过访问限制,则继续执行对应业务逻辑
            return jp.proceed();
        } else {
            // 超过访问限制,则返回默认熔断响应结果(即注解中的returnJson)
            return JSON.parseObject(doRateLimiter.returnJson());
        }
    }
}

测试

controller如下,仅允许一个并发

压测两个并发

result:尝试拿一个许可(RateLimiter.tryAcquire())未拿到(即超频),返回注解中的returnJson()

到此这篇关于SpringBoot中间件封装限流器的文章就介绍到这了,更多相关SpringBoot限流器内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • eclipse上配置Maven的图文教程(推荐)

    eclipse上配置Maven的图文教程(推荐)

    下面小编就为大家分享一篇eclipse上配置Maven的图文教程(推荐),具有很好的参考价值。希望对大家有所帮助。一起跟随小编过来看看吧
    2017-11-11
  • Java中的自动装箱与自动拆箱的实现

    Java中的自动装箱与自动拆箱的实现

    自动装箱和自动拆箱使得我们在使用基本数据类型时更加方便,同时也提高了代码的可读性和健壮性,本文将详细介绍Java中的自动装箱和自动拆箱机制,感兴趣的可以了解一下
    2023-08-08
  • SparkSQL读取hive数据本地idea运行的方法详解

    SparkSQL读取hive数据本地idea运行的方法详解

    这篇文章主要介绍了SparkSQL读取hive数据本地idea运行的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-09-09
  • Java+opencv3.2.0实现人脸检测功能

    Java+opencv3.2.0实现人脸检测功能

    这篇文章主要为大家详细介绍了Java+opencv3.2.0实现人脸检测功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-02-02
  • Java定时器Timer与TimerTask的使用详解

    Java定时器Timer与TimerTask的使用详解

    这篇文章主要介绍了Java定时器Timer与TimerTask的使用详解,在JDK类库中Timer主要负责计划任务的功能,也就是在指定时间执行某一任务,执行时候会在主线程之外起一个单独的线程执行指定的任务,该类主要是设置任务计划,但封装的类是TimerTask类,需要的朋友可以参考下
    2023-10-10
  • Mybatis分页的4种方式实例

    Mybatis分页的4种方式实例

    这篇文章主要介绍了Mybatis分页的4种方式实例,包括数组分页,sql分页,拦截器分页,RowBounds分页,需要的朋友可以参考下
    2022-04-04
  • Java设计模式中的建造者(Builder)模式解读

    Java设计模式中的建造者(Builder)模式解读

    这篇文章主要介绍了Java设计模式中的建造者(Builder)模式解读, 建造者模式是一种创建对象的设计模式,它通过将对象的构建过程分解为多个步骤,并使用一个建造者类来封装这些步骤,从而使得对象的构建过程更加灵活和可扩展,需要的朋友可以参考下
    2023-10-10
  • SpringBoot 实战 之 优雅终止服务的方法

    SpringBoot 实战 之 优雅终止服务的方法

    本篇文章主要介绍了SpringBoot 实战 之 优雅终止服务的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-05-05
  • 用Java实现希尔排序的示例

    用Java实现希尔排序的示例

    问题:现有一段程序S,可以对任意n个数进行排序。如果现在需要对n^2个数进行排序,最少需要调用S多少次?只允许调用S,不可以做别的操作。我们用希尔排序来做解决这个
    2013-11-11
  • MyBatis Generator的简单使用方法示例

    MyBatis Generator的简单使用方法示例

    这篇文章主要给大家介绍了关于MyBatis Generator的简单使用方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-02-02

最新评论