千家信息网

如何实现redis限流

发表于:2026-11-03 作者:千家信息网编辑
千家信息网最后更新 2026年11月03日,如何实现redis限流?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。redis限流的实现方式有3种,分别是:第一种:基于Redis的
千家信息网最后更新 2026年11月03日如何实现redis限流

如何实现redis限流?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。

redis限流的实现方式有3种,分别是:

第一种:基于Redis的setnx的操作

我们在使用Redis的分布式锁的时候,大家都知道是依靠了setnx的指令,在CAS(Compare and swap)的操作的时候,同时给指定的key设置了过期实践(expire),我们在限流的主要目的就是为了在单位时间内,有且仅有N数量的请求能够访问我的代码程序。所以依靠setnx可以很轻松的做到这方面的功能。

比如我们需要在10秒内限定20个请求,那么我们在setnx的时候可以设置过期时间10,当请求的setnx数量达到20时候即达到了限流效果。代码比较简单就不做展示了。

当然这种做法的弊端是很多的,比如当统计1-10秒的时候,无法统计2-11秒之内,如果需要统计N秒内的M个请求,那么我们的Redis中需要保持N个key等等问题

第二种:基于Redis的数据结构zset

其实限流涉及的最主要的就是滑动窗口,上面也提到1-10怎么变成2-11。其实也就是起始值和末端值都各+1即可。

而我们如果用Redis的list数据结构可以轻而易举的实现该功能

我们可以将请求打造成一个zset数组,当每一次请求进来的时候,value保持唯一,可以用UUID生成,而score可以用当前时间戳表示,因为score我们可以用来计算当前时间戳之内有多少的请求数量。而zset数据结构也提供了range方法让我们可以很轻易的获取到2个时间戳内有多少请求

代码如下

public Response limitFlow(){        Long currentTime = new Date().getTime();        System.out.println(currentTime);        if(redisTemplate.hasKey("limit")) {            Integer count = redisTemplate.opsForZSet().rangeByScore("limit", currentTime -  intervalTime, currentTime).size();        // intervalTime是限流的时间             System.out.println(count);            if (count != null && count > 5) {                return Response.ok("每分钟最多只能访问5次");            }        }        redisTemplate.opsForZSet().add("limit",UUID.randomUUID().toString(),currentTime);        return Response.ok("访问成功");    }

通过上述代码可以做到滑动窗口的效果,并且能保证每N秒内至多M个请求,缺点就是zset的数据结构会越来越大。实现方式相对也是比较简单的。

第三种:基于Redis的令牌桶算法

提到限流就不得不提到令牌桶算法了。令牌桶算法又称之为水桶算法,具体可以参照度娘的解释 令牌桶算法

令牌桶算法提及到输入速率和输出速率,当输出速率大于输入速率,那么就是超出流量限制了。

也就是说我们每访问一次请求的时候,可以从Redis中获取一个令牌,如果拿到令牌了,那就说明没超出限制,而如果拿不到,则结果相反。

依靠上述的思想,我们可以结合Redis的List数据结构很轻易的做到这样的代码

依靠List的leftPop来获取令牌

// 输出令牌public Response limitFlow2(Long id){        Object result = redisTemplate.opsForList().leftPop("limit_list");        if(result == null){            return Response.ok("当前令牌桶中无令牌");        }        return Response.ok(articleDescription2);    }

再依靠Java的定时任务,定时往List中rightPush令牌,当然令牌也需要唯一性,所以我这里还是用UUID进行了生成

// 10S的速率往令牌桶中添加UUID,只为保证唯一性    @Scheduled(fixedDelay = 10_000,initialDelay = 0)    public void setIntervalTimeTask(){        redisTemplate.opsForList().rightPush("limit_list",UUID.randomUUID().toString());    }

综上,代码实现起始都不是很难,针对这些限流方式我们可以在AOP或者filter中加入以上代码,用来做到接口的限流,最终保护你的网站。

Redis其实还有很多其他的用处,他的作用不仅仅是缓存,分布式锁的作用。他的数据结构也不仅仅是只有String,Hash,List,Set,Zset。有兴趣的可以后续了解下他的GeoHash算法;BitMap,HLL以及布隆过滤器数据(Redis4.0之后加入,可以用Docker直接安装redislabs/rebloom)结构。

关于如何实现redis限流问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注行业资讯频道了解更多相关知识。

令牌 代码 数据 时候 算法 结构 数据结构 时间 速率 就是 问题 数量 方式 统计 输出 不仅仅 也就是 作用 分布式 功能 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 科技信息互联网 金融科技创新监管互联网金融 善班互联网科技有限公司 互联网金融科技委员会 海南科技产业互联网平台 富国互联网科技创新基金 银川新华互联网科技学校地址 济南华为互联网科技产业总部基地 温州喔噻互联网科技有限公司 北京华百购互联网科技有限公司 互联网科技商业 西安小鹰速贷互联网科技有限公司 互联网科技的全部知识 互联网科技大赛获奖感言 互联网时代的科技公司 广州互联网高科技取餐柜 信承诺互联网科技有限公司 互联网科技平台产品运营 互联网科技自媒体灵感 株洲百竞科技的互联网营销顾问 湖北九亚互联网络科技有限公司 互联网科技公司税收优惠 智慧科技互联网 恒生科技互联网指数分析 互联网金融科技公司干啥的 重庆互联网医院沙龙医盟信息科技 崇明区互联网教育科技售后服务 玉溪新华互联网科技好不好 易企秀互联网科技是做什么的 科技和互联网行业的特点
0