Redis 限流的 3 种方式,还有谁不会

使用Redis实现限流 使用Redis实现限流的三种方式目录概述基于计数器的固定窗口限流实现原理适用场景实现步骤代码实现缺点基于滑动窗口的限流实现原理适用场景实现步骤代码实现优点缺点基于令牌桶算法的限流实现原理适用场景实现步骤Lua脚本实现Java实现优点缺点总结概述在分布式系统中,限流是保护服务的重要手段之一。通过限流,可以防止接口被恶意刷请求... 阅读详情

面对越来越多的高并发场景,限流显示的尤为重要。

当然,限流有许多种实现的方式,Redis具有很强大的功能,我用Redis实践了三种的实现方式,可以较为简单的实现其方式。Redis不仅仅是可以做限流,还可以做数据统计,附近的人等功能,这些可能会后续写到。

1第一种:基于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等等问题。

2第二种:基于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的数据结构会越来越大。实现方式相对也是比较简单的。

3第三种:基于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)结构。

Java 实现 Redis 5种限流算法 Redis 6.0 引入了新的命令 CL.THROTTLE,这是 Redis 内置的限流功能,可以用来实现令牌桶限流算法。通过 CL.THROTTLE,可以在 Redis 服务器端实现限流逻辑,从而避免了客户端与 Redis 之间的多次交互。Redis 6.0 提供了一个模块 redis-cell,其中包含了 CL.THROTTLE 命令,可以用于实现令牌桶限流算法。每当有请求时,从桶中取出一个令牌,如果桶中没有令牌,则进行限流。// 获取桶的当前状态,如果桶为空,则初始化桶容量和上次漏出时间。 阅读详情

相关推荐

从个体到群体:Cartool实战静息态EEG微状态聚类全解析

本文详细解析了使用Cartool软件进行静息态EEG微状态聚类的完整实战流程。从个体水平聚类到群体模板提取,再到指标量化,文章深入探讨了k-means算法的应用、GFP峰值数据的使用技巧以及关键参数设置,为脑电信号处理研究者提供了从数据准备到结果解读的全方位指南。

weixin_29062671的博客 290

令牌桶(Token Bucket)

概要   限流可以认为服务降级的一种,限流就是限制系统的输入和输出流量已达到保护系统的目的。一般来说系统的吞吐量是可以被测算的,为了保证系统的稳定运行,一旦达到的需要限制的阈值,就需要限制流量并采取一些措施以完成限制流量的目的。比如:延迟处理,拒绝处理,或者部分拒绝处理等等。 令牌桶算法   令牌桶算法的原理是系统会以一个恒定的速度往桶里放入令牌,而如果请求需要被处理,则需要...

a624575745856085的博客 1346

cst-python联合仿真的问题解决

cst与python联合仿真出现无法调用CST的问题解决

ayihu_的博客 2375

Redis命令实战:使用场景记录

String类型 计数器类 INCR key 相当于 i++ 将key中储存的数字值增一。如果key不存在,那么key的值会先被初始化为0,然后再执行INCR操作。 INCRBY key increment 相当于 i +=increment 将key所储存的值加上增量increment。如果key不存在,那么key的值会先被初始化为0,然后再执行INCRBY命令。 INCRBYFLOAT key increment 为key中所储存的值...

daima_caigou的博客 1364

JW01二氧化碳传感器实战:5分钟搞定Arduino环境监测系统(附完整代码)

本文详细介绍了如何使用JW01二氧化碳传感器与Arduino快速搭建环境监测系统。通过简单的硬件连接和完整的代码示例,读者可以在5分钟内实现CO2浓度实时监测,并了解数据解析、常见问题解决及进阶应用扩展。JW01传感器的高精度和易用性使其成为创客和嵌入式开发者的理想选择。

kite3的博客 383

NET 实战:30 天搞定企业级 Web 订餐系统(附完整源码 + 数据库设计)

订餐流程:浏览菜品 → 选择菜品及数量 → 填写送餐地址 → 提交订单 → 数据库记录核心代码(绑定菜品列表):vb' 绑定菜单表到DataGrid控件,展示菜品信息user id=sa;' 查询菜品名称、价格、口味Dim adpt1 As New SqlDataAdapter("select cdishid,vdishname 菜品名称,cdishrate 价格,vdishdescription 口味 from dish", conn)End Sub用户体验优化。

m0_67740236的博客 1518

【技术详解】Java中使用Redis实现多规则限流:从原理到实践(高级篇)

限流是现代高并发系统设计中不可或缺的一部分,它能够有效防止系统过载崩溃,保障系统的稳定性和可用性。限流的应用场景非常广泛,例如在网络爬虫控制、API接口访问限制、消息队列保护等方面。由于Redis具有高性能、分布式特性以及丰富的数据结构,因此成为实现限流策略的理想选择。本文主要面向Java开发者和系统架构师,旨在详细介绍如何利用Redis在Java应用程序中实现多种限流策略。

欢迎来到我的技术空间!我是一名经验丰富的Java开发工程师,热衷于分享我在软件开发领域的知识和心得。在这个博客里,您会发现一系列关于Java编程的文章,包括最佳实践、技术趋势、代码优化技巧以及一些有趣的项目案例。无论是初学者还是有经验的开发者,都能在这里找 2922

基于opencv自定义网格板的相机标定软件源码

本软件开发版使用的是VS2013和QT5.7, 安装版的需要安装VS核心库(目录里的vcredist_x64.exe, 已安装VS的不需要)。采用强大的模板匹配算法,本程序适用于自定义大范围网格标定(本例程网格使用的是自己画的网格板31*21*10cm),网格点识别度高,矫正速度快,精度高。 使用步骤 第1步: 打开图片,打开标定工具GridCalibTool.exe, 然后选择打开一张待标定的图(CalibFiles文件夹下的500.jpg)。如下图: 第2步: 提取待标定区域(去掉多余部分,只保留网

qq_33138437的博客 1123

Redis学习三:Redis数据类型

一、Redis的五大数据类型 1.String(字符串) string是redis最基本的类型,你可以理解成与Memcached一模一样的类型,一个key对应一个value。string类型是二进制安全的。意思是redis的string可以包含任何数据。比如jpg图片或者序列化的对象 。string类型是Redis最基本的数据类型,一个redis中字符串value最多可以是512M 2.Ha...

weixin_30566111的博客 240

【WorkBuddy专栏39】零基础也能做小程序——WorkBuddy微信小程序开发完全指南

【WorkBuddy专栏39】零基础也能做小程序——WorkBuddy微信小程序开发完全指南

AI人人懂 3195

PCL 三维重建 基于B样条曲线的曲面重建算法

本文将介绍如何使用B样条曲线进行三维点云数据的曲面重建。B样条曲线和曲面是一种强大的数学工具,在计算机图形学、CAD设计等领域中广泛应用。通过对点云数据进行曲面拟合和优化,最终得到精确的曲面模型。本示例展示了如何利用PCL中的B样条曲线拟合算法进行三维曲面重建,并对重建结果进行可视化。

纵马踏花向自由 658

Redis 限流的 3 种方式,还有谁不会!

点击关注公众号,Java干货及时送达面对越来越多的高并发场景,限流显示的尤为重要。当然,限流有许多种实现的方式,Redis具有很强大的功能,我用Redis实践了三种的实现方式,可以较为简单...

Java技术栈,分享最主流的Java技术 389

【GlobalMapper精品教程】027:路径剖面和和视线工具的使用

路径剖面视线工具允许您使用加载的高程数据集沿用户指定的路径获取垂直剖面。要定义生成3D路径剖面所遵循的路径,只需单击鼠标左键选择路径的点,然后石键单击以结束路径。出现一个带有剖面的对话框,允许您设置视线分析或优化端点。

智慧空间实验室 2051

Redis 限流的 3 种方式,还有谁不会?

面对越来越多的高并发场景,限流显示的尤为重要。 当然,限流有许多种实现的方式,Redis具有很强大的功能,我用Redis实践了三种的实现方式,可以较为简单的实现其方式。Redis不仅仅是可以做限流,还可以做数据统计,附近的人等功能,这些可能会后续写到。 第一种:基于Redis的setnx的操作 我们在使用Redis的分布式锁的时候,大家都知道是依靠了setnx的指令,在CAS(Compare and swap)的操作的时候,同时给指定的key设置了过期实践(expire),我们在限流的主要目的就是..

欢迎来到我的博客 128

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

Redis 限流的 3 种方式,还有谁不会..

面对越来越多的高并发场景,限流显示的尤为重要。 当然,限流有许多种实现的方式,Redis具有很强大的功能,我用Redis实践了三种的实现方式,可以较为简单的实现其方式。Redis不仅仅是可以做限流,还可以做数据统计,附近的人等功能,这些可能会后续写到。 第一种:基于Redis的setnx的操作 我们在使用Redis的分布式锁的时候,大家都知道是依靠了setnx的指令,在CAS(Compare and swap)的操作的时候,同时给指定的key设置了过期实践(expire),我们在限流的主要目的就是为了在单位

Java技术栈,分享最主流的Java技术 197

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

Redis 实现限流的三种方式

这些面试题是我朋友进阿里前狂刷七遍以上的面试资料,由于面试文档很多,内容更多,没有办法一一为大家展示出来,所以只好为大家节选出来了一部分供大家参考。面试的本质不是考试,而是告诉面试官你会做什么,所以,这些面试资料中提到的技术也是要学会的,不然稍微改动一下你就凉凉了。

2401_84048542的博客 979

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

基于Redis的分布式限流详解

本文主要介绍了基于Redis通过Lua脚本实现分布式限流的几种方案。 1、4种典型的限流算法:固定时间窗口,滑动时间窗口,漏桶,令牌牌。 2、通过Lua脚本实现4种典型的分流算法。 3、其他限流实现方案介绍:Guava的RateLimiter、Redisson的RRateLimiter、Redis的redis-cell限流模块、Nginx 限流、 Spring Cloud Gateway网关限流、阿里的sentinel限流、信号量Semaphore单机并发限流、Bucket4j和Resilience4j限流

弹指天下 9491

Redis 限流的 3 种方式,速速拿走

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

tuonioooo 3650

【Spring】SpringBoot整合Redis,用Redis实现限流(附Redis解压包)

本文介绍SpringBoot整合Redis并且进行接口的限流,文章主要介绍的是一种思想,具体代码还要结合实际。

qq_61024956的博客 6546

Redis 限流的 3 种方式你都会了吗?

前言 面对越来越多的高并发场景,限流显示的尤为重要。 当然,限流有许多种实现的方式,Redis具有很强大的功能,我用Redis实践了三种的实现方式,可以较为简单的实现其方式。Redis不仅仅是可以做限流,还可以做数据统计,附近的人等功能,这些可能会后续写到。 正文 第一种:基于Redis的setnx的操作 我们在使用Redis的分布式锁的时候,大家都知道是依靠了setnx的指令,在CAS(Compare and swap)的操作的时候,同时给指定的key设置了过期实践(expire),我们在限流的主要目的就

ZXZN027的博客 5994

Redis 限流的 3 种方式

大家好,我是DD。现在出去面试各种后端开发岗位,高并发场景相关的题基本是不会少的。而在高并发场景下,限流又是非常重要的一块。今天就来聊聊限流的解决方案。当然,限流有许多种实现的方式,Red...

程序猿DD 477
上一篇: Redis缓存使用技巧和设计方案
下一篇: 个人笔记,深入理解 JVM,很全
JavaMonsterr
博客等级 码龄4年 211粉丝 481原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值