Redisson 限流器源码分析

对上篇文章网友评论给出问题进行解答:redis 的key 是否会过期

可以先阅读上篇文章:

redis + AOP + 自定义注解实现接口限流 - 古渡蓝按 - 博客园 (cnblogs.com)

注解AOP 代码部分提取

  1. // 调用Reids工具类的rateLimiter 方法
  2. long number = RedisUtils.rateLimiter(combineKey, rateType, count, time);

redis 工具类

  1. public class RedisUtils {
  2. private static final RedissonClient CLIENT = SpringUtils.getBean(RedissonClient.class);
  3. /**
  4. * 限流
  5. *
  6. * @param key 限流key
  7. * @param rateType 限流类型
  8. * @param rate 速率
  9. * @param rateInterval 速率间隔
  10. * @return -1 表示失败
  11. */
  12. public static long rateLimiter(String key, RateType rateType, int rate, int rateInterval) {
  13. // 获取一个限流器
  14. RRateLimiter rateLimiter = CLIENT.getRateLimiter(key);
  15. // 将限流的配置信息保存在Redis中
  16. rateLimiter.trySetRate(rateType, rate, rateInterval, RateIntervalUnit.SECONDS);
  17. // tryAcquire 用于获取当前可用的许可数
  18. if (rateLimiter.tryAcquire()) {
  19. return rateLimiter.availablePermits();
  20. } else {
  21. return -1L;
  22. }
  23. }
  24. }

解析

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

源码分析

源码截图:



1.

分析:trySetRate 调用 trySetRateAsync 方法

  1. @Override
  2. public boolean trySetRate(RateType type, long rate, long rateInterval, RateIntervalUnit unit) {
  3. return get(trySetRateAsync(type, rate, rateInterval, unit));
  4. }
  5. @Override
  6. public RFuture<Boolean> trySetRateAsync(RateType type, long rate, long rateInterval, RateIntervalUnit unit) {
  7. return commandExecutor.evalWriteNoRetryAsync(getRawName(), LongCodec.INSTANCE, RedisCommands.EVAL_BOOLEAN,
  8. "redis.call('hsetnx', KEYS[1], 'rate', ARGV[1]);"
  9. + "redis.call('hsetnx', KEYS[1], 'interval', ARGV[2]);"
  10. + "return redis.call('hsetnx', KEYS[1], 'type', ARGV[3]);",
  11. Collections.singletonList(getRawName()), rate, unit.toMillis(rateInterval), type.ordinal());
  12. }

逐步分析代码:

  • commandExecutor.evalWriteNoRetryAsync():这里使用了 Redis 的 EVAL 命令,这个命令允许执行 Lua 脚本,而不会受到 Redis 的同步阻塞操作。
  • getRawName():这是获取限流器的名称或标识。
  • RedisCommands.EVAL_BOOLEAN:表示执行 Lua 脚本后期望的返回值类型为 Boolean。

源码lua 脚本解释

  1. -- 源码lua 脚本
  2. "redis.call('hsetnx', KEYS[1], 'rate', ARGV[1]);"
  3. + "redis.call('hsetnx', KEYS[1], 'interval', ARGV[2]);"
  4. + "return redis.call('hsetnx', KEYS[1], 'type', ARGV[3]);"
  5. --- 解释
  6. 这段 Lua 脚本中,通过 redis.call('hsetnx', KEYS[1], 'rate', ARGV[1]) 等命令,尝试对 Redis Hash 数据结构进行设置操作。
  7. 首先尝试设置 'rate' 字段为传入的速率值;
  8. 然后尝试设置 'interval' 字段为传入的时间间隔值;
  9. 最后尝试设置 'type' 字段为传入的类型值。这里使用了 hsetnx 命令来进行设置操作,如果字段已存在,则不会进行设置操作。
  • Collections.singletonList(getRawName()):将限流器的名称作为参数传递给 Lua 脚本。
  • rate, unit.toMillis(rateInterval), type.ordinal():这三个参数分别是速率、时间间隔以毫秒为单位、以及限流类型

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

设置限流器的失效时间

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

修改后代码:

  1. /**
  2. * 限流
  3. *
  4. * @param key 限流key
  5. * @param rateType 限流类型
  6. * @param rate 速率
  7. * @param rateInterval 速率间隔
  8. * @param expirationTimeInSeconds 过期时间(秒)
  9. * @param isExpire 是否设置限流器过期
  10. * @return -1 表示失败
  11. */
  12. public static long rateLimiter(String key, RateType rateType, int rate, int rateInterval, long expirationTimeInSeconds,boolean isExpire) {
  13. RRateLimiter rateLimiter = CLIENT.getRateLimiter(key);
  14. rateLimiter.trySetRate(rateType, rate, rateInterval, RateIntervalUnit.SECONDS);
  15. if(isExpire){
  16. // 是否设置过期时间
  17. rateLimiter.expire(expirationTimeInSeconds, TimeUnit.SECONDS);
  18. }
  19. if (rateLimiter.tryAcquire()) {
  20. return rateLimiter.availablePermits();
  21. } else {
  22. return -1L;
  23. }
  24. }

如果代码写的有问题,欢迎大家评论交流,进行指点!!!

也希望大家点个关注哦~~~~~~~~

Redisson 限流器源码分析的更多相关文章

  1. 时间轮机制在Redisson分布式锁中的实际应用以及时间轮源码分析

    本篇文章主要基于Redisson中实现的分布式锁机制继续进行展开,分析Redisson中的时间轮机制. 在前面分析的Redisson的分布式锁实现中,有一个Watch Dog机制来对锁键进行续约,代码 ...

  2. Redisson分布式锁学习总结:可重入锁 RedissonLock#lock 获取锁源码分析

    原文:Redisson分布式锁学习总结:可重入锁 RedissonLock#lock 获取锁源码分析 一.RedissonLock#lock 源码分析 1.根据锁key计算出 slot,一个slot对 ...

  3. Springboot基于Redisson实现Redis分布式可重入锁【案例到源码分析】

    一.前言 我们在实现使用Redis实现分布式锁,最开始一般使用SET resource-name anystring NX EX max-lock-time进行加锁,使用Lua脚本保证原子性进行实现释 ...

  4. RedissonLock分布式锁源码分析

    最近碰到的一个问题,Java代码中写了一个定时器,分布式部署的时候,多台同时执行的话就会出现重复的数据,为了避免这种情况,之前是通过在配置文件里写上可以执行这段代码的IP,代码中判断如果跟这个IP相等 ...

  5. 【JDK】JDK源码分析-Semaphore

    概述 Semaphore 是并发包中的一个工具类,可理解为信号量.通常可以作为限流器使用,即限制访问某个资源的线程个数,比如用于限制连接池的连接数. 打个通俗的比方,可以把 Semaphore 理解为 ...

  6. [源码分析] OpenTracing之跟踪Redis

    [源码分析] OpenTracing之跟踪Redis 目录 [源码分析] OpenTracing之跟踪Redis 0x00 摘要 0x01 总体逻辑 1.1 相关概念 1.2 埋点插件 1.3 总体逻 ...

  7. ABP源码分析一:整体项目结构及目录

    ABP是一套非常优秀的web应用程序架构,适合用来搭建集中式架构的web应用程序. 整个Abp的Infrastructure是以Abp这个package为核心模块(core)+15个模块(module ...

  8. HashMap与TreeMap源码分析

    1. 引言     在红黑树--算法导论(15)中学习了红黑树的原理.本来打算自己来试着实现一下,然而在看了JDK(1.8.0)TreeMap的源码后恍然发现原来它就是利用红黑树实现的(很惭愧学了Ja ...

  9. nginx源码分析之网络初始化

    nginx作为一个高性能的HTTP服务器,网络的处理是其核心,了解网络的初始化有助于加深对nginx网络处理的了解,本文主要通过nginx的源代码来分析其网络初始化. 从配置文件中读取初始化信息 与网 ...

  10. zookeeper源码分析之五服务端(集群leader)处理请求流程

    leader的实现类为LeaderZooKeeperServer,它间接继承自标准ZookeeperServer.它规定了请求到达leader时需要经历的路径: PrepRequestProcesso ...

随机推荐

  1. java操作xml超简单的方法

    用dom4j?SAX?no,no,no,光看api和帮助文档就烦,有没有更简单的方法呢?答案是有的. 那就是默默无名的:JAXB jaxb是啥? 摘抄一段度娘百科的介绍: JAXB能够使用Jackso ...

  2. async与await暂停作用

    1. async function Request () { await new Promise(res => { setTimeout(() => { console.log(1) re ...

  3. 优化搜索排序结果从而“ 提升CTR、CVR业务指标”

    简介: 搭建搜索功能不难,难的是如何提高搜索质量,帮助用户快速找到心中所想的内容或商品,那么搜索结果的相关性排序则是影响用户体验最关键的一环,本文通过阿里云开放搜索电商行业解决方案和大家聊一聊如何优化 ...

  4. 如何保证 Serverless 业务部署更新的一致性?

    简介: 代码在其他场景被更新,需要我们在当前得到感知,这个事情其实是非常重要的,和代码的安全发布密不可少.而此时,通过 Serverless Devs 是可以做到的. 作者|Anycodes​ 从我做 ...

  5. netcore热插拔dll

    项目中有有些场景用到反射挺多的,用到了反射就离不开dll的加载.此demo适用于通过反射dll运行项目中加载和删除,不影响项目. ConsoleApp: 1 using AppClassLibrary ...

  6. CPU是什么?

    在程序是怎样跑起来的这本书中我们首先被询问的一个问题是"程序是什么?它是有什么组成的?而CPU又与程序有什么关系呢?",若我们能知道前两个,其实更容易将你带入讨论"CPU ...

  7. c#胖东来小程序自动购物程序(接单,windows桌面程序、linux程序、网络应用等等)

    一.程序效果 自动打开胖东来小程序,自动购物 二.实现 先截屏,然后利用opencv库识别下一步按键所在位置,然后使用mouse_event控制鼠标,模拟人的动作 第一步,截取屏幕 static Bi ...

  8. 八、Dataphin

    Dataphin是阿里巴巴集团OneData数据治理方法论内部实践的云化输出,一站式提供数据采.建.管.用全生命周期的大数据能力,以助力企业显著提升数据治理水平,构建质量可靠.消费便捷.生产安全经济的 ...

  9. shell 去掉逗号_shell替换和去掉换行符

    用shell处理文件的时候我们常常需要去掉或者加上换行符,name问题就来了怎么才能快速的替换呢? 我们有这样一个文件[root@hxy working]# cat 1 GD200A16C013493 ...

  10. LVS负载均衡(1)-- LVS概述及LVS网络模型

    目录 1. 负载均衡集群概述 2. LVS理论基础 2.1 LVS常用术语 2.2 LVS数据调度原理 2.3 LVS工作模型 2.3.1 NAT模型 2.3.2 DR模型 2.3.3 TUNNEL模 ...