当前位置: 代码网 > it编程>数据库>Redis > redisson滑动时间窗应用场景解决方案

redisson滑动时间窗应用场景解决方案

2024年05月19日 Redis 我要评论
概述前10分钟内累计3次验证失败后,增加图形验证码验证条件,前10分钟内累计6次验证失败后,系统自动锁定该账号15分钟,15分钟后自动解锁;方案基于redisson(zset)滑动时间窗记录最近10分

概述

前10分钟内累计3次验证失败后,增加图形验证码验证条件,前10分钟内累计6次验证失败后,系统自动锁定该账号15分钟,15分钟后自动解锁;

方案

基于redisson(zset)滑动时间窗记录最近10分钟内该账户登录失败次数

统计次数、每次失败加1

  /**
     * 统计请求次数
     *
     * @param windowtime 窗口时间,单位:秒
     * @param key        登录账户
     * @return 请求次数
     */
    public integer count(int windowtime, string key) {
        // 窗口结束时间
        long windowendtime = system.currenttimemillis();
        // 窗口开始时间
        long windowstarttime = windowendtime - windowtime * 1000l;
        try {
            // 创建 rbatch 实例,批量执行命令
            rbatch batch = redissonclient.createbatch();
            // 添加元素 score=当前时间戳 value=请求序列号,唯一不可重复
            batch.getscoredsortedset(key).addasync(windowendtime, uuid.randomuuid().tostring());
            // 统计数据
            batch.getscoredsortedset(key).countasync(windowstarttime, true, windowendtime, true);
            // 清除窗口过期成员
            batch.getscoredsortedset(key).removerangebyscoreasync(0, true, windowstarttime, false);
            // 设置key过期时间
            batch.getscoredsortedset(key).expireasync(duration.ofseconds(windowtime));
            // 执行管道命令
            batchresult<?> batchresult = batch.execute();
            // 返回统计数量
            list<?> responses = batchresult.getresponses();
            integer number = (integer) responses.get(1);
            return number;
        } catch (exception e) {
            log.error("统计请求次数异常!", e);
            return null;
        }
    }

获取登录失败次数

/**
     * 获取对应窗口的次数
     * @param windowtime 窗口大小十分钟,600s
     * @param key
     * @return
     */
    public integer getlastcachedcount(int windowtime, string key) {
        // 窗口结束时间
        long windowendtime = system.currenttimemillis();
        // 窗口开始时间
        long windowstarttime = windowendtime - windowtime * 1000l;
        try {
            // 创建 rbatch 实例,批量执行命令
            rbatch batch = redissonclient.createbatch();
            // 统计数据,获取上一次缓存存取的数据
            rfuture<integer> countfuture = batch.getscoredsortedset(key).countasync(windowstarttime, true, windowendtime, true);
            // 执行管道命令
            batch.execute();
            // 等待统计数据完成并获取结果
            integer count = countfuture.get();
// 如果结果为null,则返回0,否则返回计数值
            return count == null ? 0 : count.intvalue();
        } catch (exception e) {
            log.error("获取上一次缓存存取数据异常!", e);
            // 如果出现异常,返回null
            return null;
        }
    }

清除登录失败次数

    public void clearcachedcount(int windowtime, string key) {
        // 窗口结束时间
        long windowendtime = system.currenttimemillis();
        // 窗口开始时间
        long windowstarttime = windowendtime - windowtime * 1000l;
        try {
            // 创建 rbatch 实例,批量执行命令
            rbatch batch = redissonclient.createbatch();
            // 统计数据,获取上一次缓存存取的数据
            batch.getscoredsortedset(key).removerangebyscoreasync(windowstarttime, true, windowendtime, true);
            // 执行管道命令
            batch.execute();
// 如果结果为null,则返回0,否则返回计数值
        } catch (exception e) {
            log.error("清楚登录失败记录次数异常", e);
        }
    }

到此这篇关于redisson滑动时间窗应用场景的文章就介绍到这了,更多相关redisson滑动时间窗内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com