redisson滑动时间窗应用场景

概述

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

方案

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

  • 统计次数、每次失败加1
java 复制代码
  /**
     * 统计请求次数
     *
     * @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;
        }
    }
  • 获取登录失败次数
java 复制代码
/**
     * 获取对应窗口的次数
     * @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;
        }
    }
  • 清除登录失败次数
java 复制代码
    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);
        }
    }
相关推荐
QH_ShareHub15 分钟前
反正态分布算法
算法
王老师青少年编程21 分钟前
csp信奥赛c++中的递归和递推研究
c++·算法·递归·递推·csp·信奥赛
Bczheng133 分钟前
五.serialize.h中的CDataStream类
算法·哈希算法
小O的算法实验室34 分钟前
2025年SEVC,考虑组件共享的装配混合流水车间批量流调度的多策略自适应差分进化算法,深度解析+性能实测
算法·论文复现·智能算法·智能算法改进
汀、人工智能38 分钟前
[特殊字符] 第36课:柱状图最大矩形
数据结构·算法·数据库架构·图论·bfs·柱状图最大矩形
List<String> error_P44 分钟前
蓝桥杯最后冲刺(三)
算法
样例过了就是过了1 小时前
LeetCode热题100 跳跃游戏
c++·算法·leetcode·贪心算法·动态规划
无限进步_1 小时前
【C++&string】寻找字符串中第一个唯一字符:两种经典解法详解
开发语言·c++·git·算法·github·哈希算法·visual studio
FluxMelodySun1 小时前
机器学习(二十九) 稀疏表示与字典学习(LASSO算法、KSVD算法、奇异值分解)
人工智能·算法·机器学习
LG.YDX1 小时前
笔试训练48天:跳台阶
数据结构·算法