首页 > 其他分享 >12.1日记

12.1日记

时间:2023-12-01 16:13:19浏览次数:43  
标签:令牌 opsForValue tokens 12.1 key refill 日记 redisTemplate

令牌桶算法

这里使用Redis实现令牌桶算法,令牌桶算法具体细节可参考其他博客,这里不赘述,大致就是在 一个时间段 内,存在一定数量的令牌,我们需要拿到令牌才可以继续操作。

所以实现思路大致就是:

    Redis 中记录上次拿取令牌的时间,以及令牌数,每个手机号对应一个桶
    每次拿令牌时,校验令牌是否足够。
/**
 * @author YukeSeko
 */
@Component
public class RedisTokenBucket {

    @Resource
    private RedisTemplate<String,String> redisTemplate;

    /**
     *  过期时间,400秒后过期
     */
    private final long EXPIRE_TIME = 400;

    /**
     * 令牌桶算法,一分钟以内,每个手机号只能发送一次
     * @param phoneNum
     * @return
     */
    public boolean tryAcquire(String phoneNum) {
        // 每个手机号码一分钟内只能发送一条短信
        int permitsPerMinute = 1;
        // 令牌桶容量
        int maxPermits = 1;
        // 获取当前时间戳
        long now = System.currentTimeMillis();
        String key = RedisConstant.SMS_BUCKET_PREFIX + phoneNum;
        // 计算令牌桶内令牌数
        int tokens = Integer.parseInt(redisTemplate.opsForValue().get(key + "_tokens") == null ? "0" : redisTemplate.opsForValue().get(key + "_tokens"));
        // 计算令牌桶上次填充的时间戳
        long lastRefillTime = Long.parseLong(redisTemplate.opsForValue().get(key + "_last_refill_time") == null ? "0" : redisTemplate.opsForValue().get(key + "_last_refill_time"));
        // 计算当前时间与上次填充时间的时间差
        long timeSinceLast = now - lastRefillTime;
        // 计算需要填充的令牌数
        int refill = (int) (timeSinceLast / 1000 * permitsPerMinute / 60);
        // 更新令牌桶内令牌数
        tokens = Math.min(refill + tokens, maxPermits);
        // 更新上次填充时间戳
        redisTemplate.opsForValue().set(key + "_last_refill_time", String.valueOf(now),EXPIRE_TIME, TimeUnit.SECONDS);
        // 如果令牌数大于等于1,则获取令牌
        if (tokens >= 1) {
            tokens--;
            redisTemplate.opsForValue().set(key + "_tokens", String.valueOf(tokens),EXPIRE_TIME, TimeUnit.SECONDS);
            // 如果获取到令牌,则返回true
            return true;
        }
        // 如果没有获取到令牌,则返回false
        return false;
    }
}



标签:令牌,opsForValue,tokens,12.1,key,refill,日记,redisTemplate
From: https://www.cnblogs.com/zhangmingmkzj/p/17869922.html

相关文章

  • 百度网盘(百度云)SVIP超级会员共享账号每日更新(2023.12.1)
    一、百度网盘SVIP超级会员共享账号可能很多人不懂这个共享账号是什么意思,小编在这里给大家做一下解答。我们多知道百度网盘很大的用处就是类似U盘,不同的人把文件上传到百度网盘,别人可以直接下载,避免了U盘的物理载体,直接在网上就实现文件传输。百度网盘SVIP会员可以让自己百度账......
  • 12.1
    打字练习P5587打字练习-洛谷|计算机科学教育新生态(luogu.com.cn)#include<iostream>#include<algorithm>#include<stack>#include<vector>#include<deque>usingnamespacestd;longlongans=0;vector<string>a,b;deque<char>s,m......
  • 一个算法笨蛋的11月leetCode刷题日记
    时间情况2021年10月29日时隔一年,第三次重做反转链表,又没做出来,太废了。2021年11月1日时隔两天,第四次重做反转链表,轻松写出【21】合并两个有序链表(思路:想象两个有序链表,需要新建两个next指向头节点的空node,一个用于最后返回.next,一个用于接收最小的node)【206】反转链表(思路:......
  • 11.29日记
    HarmonyOS是一款面向万物互联时代的、全新的分布式操作系统。在传统的单设备系统能力基础上,HarmonyOS提出了基于同一套系统能力、适配多种终端形态的分布式理念,能够支持手机、平板、智能穿戴、智慧屏、车机等多种终端设备,提供全场景(移动办公、运动健康、社交通信、媒体娱乐等)业务......
  • 2023.11.29 日记 Take it easy
    很不想把文化课写到日记里。但今天有点烦了。考试考的内容是要通过刷题得知的,并非学习。我已经在别的平台抱怨过很多次当今教育现状了,无济于事是肯定的,反而会打消学习的积极性。由于训练原因欠了很多课,再加上两个学校的进度不同、考试时间不同,我的学习成果实在像是被虫蛀了一样......
  • 11.28日记
    SQL方式操作1.实例化SparkContext和SparkSession对象2.创建caseclassEmp样例类,用于定义数据的结构信息3.通过SparkContext对象读取文件,生成RDD[String]4.将RDD[String]转换成RDD[Emp]5.引入spark隐式转换函数(必须引入)6.将RDD[Emp]转换成DataFrame7.将DataFrame注册成一张视图或......
  • 文心一言 VS 讯飞星火 VS chatgpt (145)-- 算法导论12.1 5题
    五、用go语言,因为在基于比较的排序模型中,完成n个元素的排序,其最坏情况下需要Ω(nlgn)时间。试证明:任何基于比较的算法从n个元素的任意序列中构造一棵二又搜索树,其最坏情况下需要Ω(nlgn)的时间。我个人喜欢灵小智。文心一言:首先,我们要明白二叉搜索树(BST)的性质:每个节点......
  • 文心一言 VS 讯飞星火 VS chatgpt (144)-- 算法导论12.1 4题
    四、用go语言,对于一棵有n个结点的树,请设计在O(n)时间内完成的先序遍历算法和后序遍历算法。我个人喜欢灵小智。文心一言:在Go语言中,我们可以使用递归来实现树的前序遍历和后序遍历。以下是实现这两种方法的代码。首先,我们定义一个树节点的结构:typeTreeNodestruct{V......
  • 文心一言 VS 讯飞星火 VS chatgpt (144)-- 算法导论12.1 4题
    四、用go语言,对于一棵有n个结点的树,请设计在O(n)时间内完成的先序遍历算法和后序遍历算法。我个人喜欢灵小智。文心一言:在Go语言中,我们可以使用递归来实现树的前序遍历和后序遍历。以下是实现这两种方法的代码。首先,我们定义一个树节点的结构:typeTreeNodestruct{......
  • 文心一言 VS 讯飞星火 VS chatgpt (143)-- 算法导论12.1 3题
    三、用go语言,设计一个执行中序遍历的非递归算法。(提示:一种容易的方法是使用栈作为辅助数据结构;另一种较复杂但比较简洁的做法是不使用栈,但要假设能测试两个指针是否相等。)文心一言,代码正常运行:我们可以使用栈作为辅助数据结构来执行中序遍历的非递归算法。以下是用Go语言实现的代......