首页 > 数据库 >解析Redisson 限流器源码

解析Redisson 限流器源码

时间:2024-09-17 10:25:37浏览次数:10  
标签:Redisson return rateLimiter param rateInterval rate 限流 源码

 工具类


public class RedisUtils {


   private static final RedissonClient CLIENT = SpringUtils.getBean(RedissonClient.class);


   /**

    * 限流

    *

    * @param key          限流key

    * @param rateType     限流类型

    * @param rate         速率

    * @param rateInterval 速率间隔

    * @return -1 表示失败

    */

   public static long rateLimiter(String key, RateType rateType, int rate, int rateInterval) {

   

       // 获取一个限流器

       RRateLimiter rateLimiter = CLIENT.getRateLimiter(key);

       // 将限流的配置信息保存在Redis中

       rateLimiter.trySetRate(rateType, rate, rateInterval, RateIntervalUnit.SECONDS);

       // tryAcquire 用于获取当前可用的许可数

       if (rateLimiter.tryAcquire()) {

           return rateLimiter.availablePermits();

       } else {

           return -1L;

       }

   }

}    


解析


rateLimiter.trySetRate(rateType, rate, rateInterval, RateIntervalUnit.SECONDS);


源码分析

源码截图:




分析:trySetRate 调用 trySetRateAsync 方法


@Override

   public boolean trySetRate(RateType type, long rate, long rateInterval, RateIntervalUnit unit) {

       return get(trySetRateAsync(type, rate, rateInterval, unit));

   }


   @Override

   public RFuture<Boolean> trySetRateAsync(RateType type, long rate, long rateInterval, RateIntervalUnit unit) {

       return commandExecutor.evalWriteNoRetryAsync(getRawName(), LongCodec.INSTANCE, RedisCommands.EVAL_BOOLEAN,

               "redis.call('hsetnx', KEYS[1], 'rate', ARGV[1]);"

             + "redis.call('hsetnx', KEYS[1], 'interval', ARGV[2]);"

             + "return redis.call('hsetnx', KEYS[1], 'type', ARGV[3]);",

               Collections.singletonList(getRawName()), rate, unit.toMillis(rateInterval), type.ordinal());

   }


逐步分析代码:


commandExecutor.evalWriteNoRetryAsync():这里使用了 Redis 的 EVAL 命令,这个命令允许执行 Lua 脚本,而不会受到 Redis 的同步阻塞操作。

getRawName():这是获取限流器的名称或标识。

RedisCommands.EVAL_BOOLEAN:表示执行 Lua 脚本后期望的返回值类型为 Boolean。

源码lua 脚本解释


– 源码lua 脚本


"redis.call('hsetnx', KEYS[1], 'rate', ARGV[1]);"

+ "redis.call('hsetnx', KEYS[1], 'interval', ARGV[2]);"

+ "return redis.call('hsetnx', KEYS[1], 'type', ARGV[3]);"


--- 解释

这段 Lua 脚本中,通过 redis.call('hsetnx', KEYS[1], 'rate', ARGV[1]) 等命令,尝试对 Redis 的 Hash 数据结构进行设置操作。

首先尝试设置 'rate' 字段为传入的速率值;

然后尝试设置 'interval' 字段为传入的时间间隔值;

最后尝试设置 'type' 字段为传入的类型值。这里使用了 hsetnx 命令来进行设置操作,如果字段已存在,则不会进行设置操作。


Collections.singletonList(getRawName()):将限流器的名称作为参数传递给 Lua 脚本。

rate, unit.toMillis(rateInterval), type.ordinal():这三个参数分别是速率、时间间隔以毫秒为单位、以及限流类型

总结:这段代码本身并没有提供设置限流器自动过期的功能。在 Redisson 中,限流器自动过期的功能通常不是默认包含在限流器的设置中。


二、设置限流器的失效时间

限流器自动过期(是指的是限流这个功能),可以使用expire进行失效时间设置


修改后代码:


/**

    * 限流

    *

    * @param key          限流key

    * @param rateType     限流类型

    * @param rate         速率

    * @param rateInterval 速率间隔

    * @param expirationTimeInSeconds 过期时间(秒)

    * @param isExpire 是否设置限流器过期

    * @return -1 表示失败

    */


public static long rateLimiter(String key, RateType rateType, int rate, int rateInterval, long expirationTimeInSeconds,boolean isExpire) {

   

   RRateLimiter rateLimiter = CLIENT.getRateLimiter(key);

   

   rateLimiter.trySetRate(rateType, rate, rateInterval, RateIntervalUnit.SECONDS);

   

   if(isExpire){

       // 是否设置过期时间

      rateLimiter.expire(expirationTimeInSeconds, TimeUnit.SECONDS);

   }

   if (rateLimiter.tryAcquire()) {

       return rateLimiter.availablePermits();

   } else {

       return -1L;

   }

}


标签:Redisson,return,rateLimiter,param,rateInterval,rate,限流,源码
From: https://blog.51cto.com/u_16270801/12036104

相关文章

  • 基于微信美食菜谱点评小程序系统毕业设计 源代码作品源码成品
      博主介绍:黄菊华老师《Vue.js入门与商城开发实战》《微信小程序商城开发》图书作者,CSDN博客专家,在线教育专家,CSDN钻石讲师;专注大学生毕业设计教育和辅导。所有项目都配有从入门到精通的基础知识视频课程,学习后应对毕业设计答辩。项目配有对应开发文档、开题报告、任务书......
  • .NET源码的在线探索:source.dot.net网站深度解析
    一个在线的.NET源码查询网站为https://source.dot.net/。这个网站为开发者提供了便捷的.NET源码查询服务,无需从GitHub等代码托管平台下载整个源代码库,即可在线浏览和查询.NET框架及相关项目的源代码。以下是该网站的一些主要功能特性:在线查询:用户可以直接在网站上搜索特......
  • 深入底层源码,剖析AQS的来龙去脉!
    这里写目录标题回顾前缀知识一、Condition的概念二、Condition底层结构三、Condition源码解析3.1newCondition()3.2await()总结主要方法:回顾如果你还没熟悉AQS中的独占锁,可以先看这篇文章的前导篇。上一篇文章是以ReentrantLock里面的加锁、解锁源码进行分......
  • 汽车资讯网站|基于springboot+vue的汽车资讯网站(源码+数据库+文档)
    汽车资讯网站目录基于springboot+vue的汽车资讯网站一、前言二、系统设计三、系统功能设计 四、数据库设计 五、核心代码 六、论文参考七、最新计算机毕设选题推荐八、源码获取:博主介绍:✌️大厂码农|毕设布道师,阿里云开发社区乘风者计划专家博主,CSDN平台Java领......
  • 企业管理|基于springboot+vue的企业OA管理系统(源码+数据库+文档)
    企业管理目录基于springboot+vue的企业OA管理系统一、前言二、系统设计三、系统功能设计 四、数据库设计 五、核心代码 六、论文参考七、最新计算机毕设选题推荐八、源码获取:博主介绍:✌️大厂码农|毕设布道师,阿里云开发社区乘风者计划专家博主,CSDN平台Java领域......
  • 智慧宿舍平台|基于Springboot+vue的智慧宿舍系统(源码+数据库+文档)
    智慧宿舍系统目录基于Springboot+vue的智慧宿舍系统一、前言二、系统设计三、系统功能设计四、数据库设计 五、核心代码 六、论文参考七、最新计算机毕设选题推荐八、源码获取博主介绍:✌️大厂码农|毕设布道师,阿里云开发社区乘风者计划专家博主,CSDN平台Java领域......
  • 电子竞技信息交流平台|基于java的电子竞技信息交流平台系统小程序(源码+数据库+文档)
    电子竞技信息交流平台系统小程序目录基于java的电子竞技信息交流平台系统小程序一、前言二、系统设计三、系统功能设计四、数据库设计 五、核心代码 六、论文参考七、最新计算机毕设选题推荐八、源码获取:博主介绍:✌️大厂码农|毕设布道师,阿里云开发社区乘风者计......
  • 课堂助手|微信课堂助手系统小程序(源码+数据库+文档)
    课堂助手|课堂助手系统小程序目录微信课堂助手系统小程序一、前言二、系统设计三、系统功能设计四、数据库设计 五、核心代码 六、论文参考七、最新计算机毕设选题推荐八、源码获取: 博主介绍:✌️大厂码农|毕设布道师,阿里云开发社区乘风者计划专家博主,CSDN平台......
  • 常见的限流算法
    限流算法是用于控制访问频率、保护系统免受过载攻击的重要手段。常见的限流算法有以下几种,每种算法都有不同的应用场景和优缺点。下面是几种常见的限流算法的详细介绍:1.计数器算法(Counter)原理计数器算法是最简单的限流算法。它在固定的时间窗口内记录请求的次数,一旦请求次......
  • 基于nodejs+vue的在线租车管理系统的设计与实现(源码+LW+调试文档+讲解等)
     目录:博主介绍:  完整视频演示:系统技术介绍:后端Java介绍前端框架Vue介绍具体功能截图:部分代码参考:  Mysql表设计参考:项目测试:项目论文:​为什么选择我:源码获取:博主介绍:  ......