美文网首页
基于Redis的简单限流

基于Redis的简单限流

作者: Mick米壳 | 来源:发表于2019-04-07 19:27 被阅读0次

BUCKET_MONITOR:保存过去{timeout}时间内的请求
BUCKET_COUNT:用于记录请求的顺序。每到达一个请求,该计数器+1
BUCKET:保留过去{timeout}时间内的成功请求

            //获取UUID
            String token = UUID.randomUUID().toString();
            long now = System.currentTimeMillis();
            //开启事务
            Transaction transaction = jedis.multi();

            //删除BUCKET_MONITOR中{timeout}时间之前的请求
transaction.zremrangeByScore((BUCKET_MONITOR + point).getBytes(), "-inf".getBytes(), String.valueOf(now - timeout).getBytes());
            //zinterstore的权重因子,使BUCKET中的score为原来的类型(即BUCKET_COUNT)
            ZParams params = new ZParams();
            params.weightsByDouble(1.0, 0.0);
            //计算交集,清除BUCKET中的过时请求,这些请求将不被考虑
            transaction.zinterstore(BUCKET + point, params, BUCKET + point, BUCKET_MONITOR + point);

            //计数器自增,记录到达的请求数
            transaction.incr(BUCKET_COUNT);
            List<Object> results = transaction.exec();
            long counter = (Long) results.get(results.size() - 1);

            //新建一个事务
            transaction = jedis.multi();
            //向两个BUCKET中添加内容,score分别为请求到达的时间和BUCKET_COUNT
            transaction.zadd(BUCKET_MONITOR + point, now, token);
            transaction.zadd(BUCKET + point, counter, token);
            transaction.zrank(BUCKET + point, token);
            results = transaction.exec();
            //获取排名(小->大),判断请求是否取得了信号量(也即是否队伍长度超限)
            long rank = (Long) results.get(results.size() - 1);
            if (rank < limit) {
                return token;
            } else {
                //没有获取到信号量,清理之前放入redis中垃圾数据
                transaction = jedis.multi();
                //Zrem移除刚才加入的score
                transaction.zrem(BUCKET_MONITOR + point, token);
                transaction.zrem(BUCKET + point, token);
                transaction.exec();
            }
        } catch (Exception e) {
            log.error("限流出错" + e.toString());
        }
        return null;
    }

相关文章

  • 基于Redis的简单限流

    BUCKET_MONITOR:保存过去{timeout}时间内的请求BUCKET_COUNT:用于记录请求的顺序。...

  • 技术博客

    1. 基于Redis实现分布式应用限流

  • 基于redis的简单限流的实现

    首先我们来看一个常见的、简单的限流策略。系统要限定用户的某个行为在指定的时间里只能允许发生N次,如何使用redis...

  • 基于redis的限流

    https://www.jianshu.com/p/b3a02dad5adb

  • 基于Redis的限流系统的设计

    本文讲述基于 Redis的限流系统的设计,主要会谈及限流系统中限流策略这个功能的设计;在实现方面,算法使用的是令牌...

  • 基于Redis的限流系统的设计

    本文讲述基于Redis的限流系统的设计,主要会谈及限流系统中限流策略这个功能的设计;在实现方面,算法使用的是令牌桶...

  • 基于Redis的限流系统的设计【转】

    基于Redis的限流系统的设计,主要会谈及限流系统中限流策略这个功能的设计;在实现方面,算法使用的是令牌桶算法来,...

  • 分布式限流 - 基于redis

    1,基于redis计数器 1)普通redis incr限流。不能保证原子性image.png2)lua脚本实现计数...

  • 分布式限流 redis-cell

    redis 4.0 以后开始支持扩展模块,redis-cell 是一个用rust语言编写的基于令牌桶算法的的限流...

  • Redis-pipeline实现简单的限流

    今天讨论分布式应用中的限流问题,这里通过redis的pipeline实现个简单的限流。这里先简单说一下pipeli...

网友评论

      本文标题:基于Redis的简单限流

      本文链接:https://www.haomeiwen.com/subject/vtfeiqtx.html