Redis的zset集合实现限流

文章介绍了如何使用Redis的有序集合(zset)来实现简单的限流功能。通过ZADD将请求时间作为值插入集合,然后使用ZREMANGE_BY_SCORE移除超出时间窗口的请求,ZCARD统计集合大小以判断是否超过限流次数,最后使用EXPIRE设置超时时间以清理过期键。
摘要由CSDN通过智能技术生成
	Redis的zset是有序集合,可以实现简单的限流功能,大致思路如下:
 /**
     * 1、先通过zadd方法把表示操作类型的key作为键插入有序集合,插入时用表示当前时间的currentTime作为值,以保证值的唯一性,同时用currentTime作为有序集合里元素的score值。
     * 2、随后通过zremrangeByScore命令去除0到距当前时间limitTime时间范围内的数据,
     * 那么通过zremrangeByScore命令就能在有序集合里去除score范围从0到距离当前限定时间的数据,这样就能确保有序集合内只存有指定时间内的元素。
     * 3、用zcard命令统计有序集合内键为key的个数,判断集合大小是否已经超过指定限流次数,确定是否需要限流。
     * 4、最后,使用expire语句设置有序集合里相关键的超时时间,这样就能确保在限流动作完成后这些键能自动删除,避免内存溢出。
     *
     * @param jedis     redis 对象
     * @param key      redis---键(key)
     * @param time    限制时间 秒(s)
     * @param num    限制次数
     */
    public static boolean canPass(ShardedJedis jedis, String key, int time, int num) {
        long currentTime = System.currentTimeMillis();
        //把请求放入zset(有序集合)
        jedis.zadd(key, currentTime, String.valueOf(currentTime));
        //去掉时间范围外(超时)的请求
        jedis.zremrangeByScore(key, 0, currentTime - time * 1000);
        //统计时间范围内总数
        Long count = jedis.zcard(key);
        //设置所有请求的超时时间
        jedis.expire(key, time + 1);
        boolean flag = num >= count;
        return flag;
    }

    /**
     * 获取token (使用redis的zset特性限流)
     *
     * @param username 用户名
     * @param sign     签名
     * @return
     */
    @PostMapping("/getToken")
    public StandardResult getToken(final ServerWebExchange exchange, String username, String sign) {
        ShardedJedis jedis = shardedJedisPool.getResource();
        //先判断该用户是否需要进行限流 (10秒内同一用户获取token次数不能超过三次)
        boolean requestType = canPass(jedis, username, 10, 3);
        if(requestType){
            //获取token业务代码......
            return StandardResult.ok(token);
        }else {
            return StandardResult.loginFailed("当前用户获取token次数过多,请稍后再试!");
        }
    }
使用Rediszset(有序集合实现限流器的方法是这样的: 1. 首先,你需要在Redis中创建一个zset来存储请求的时间戳和对应的分数。时间戳表示请求的时间,而分数表示请求的顺序或优先级。你可以使用当前时间戳作为分数。 2. 当有请求到达时,你可以使用ZADD命令将当前时间戳和请求的顺序或优先级添加到zset中。 3. 接下来,你可以使用ZREMRANGEBYSCORE命令来删除过期的时间戳,以保持zset的大小。 4. 然后,你可以使用ZCARD命令获取zset的大小,即当前的请求数量。 5. 如果当前请求数量大于你设置的阈值,就可以通过拒绝请求或返回错误信息来限制请求的流量。 需要注意的是,你可以根据具体需求对zset实现进行调整,例如设置一个时间窗口来限制在某个时间段内的请求数量。 引用提供了关于使用Rediszset实现限流器的方法。这种方法可以通过在zset中存储请求的时间戳和分数来实现对请求的限制。通过使用相关的Redis命令,如ZADD、ZREMRANGEBYSCORE和ZCARD,你可以实现对请求流量的控制。这种方法可以用于保护你的服务免受过多的请求压力。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [用Redis中的zset实现一个限流器](https://blog.csdn.net/qq_33240946/article/details/112436548)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [redis限流算法.zip](https://download.csdn.net/download/weixin_44107914/12572623)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值