• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

基于Springboot + aop + Lua 的Redis 分布式限流器

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

一、什么是限流?为什么要限流?

限流是保证系统高可用的重要手段!!!

由于互联网公司的流量巨大,系统上线会做一个流量峰值的评估,尤其是像各种秒杀促销活动,为了保证系统不被巨大的流量压垮,会在系统流量达到一定阈(yu)值时,拒绝掉一部分流量。

限流会导致用户在短时间内(这个时间段是毫秒级别的)系统不可用,一般我们衡量系统处理能力的指标是每秒的QPS或者TPS,假设系统每秒的流量阈值是1000,理论上一秒内有第1001个请求进来时,那么这个请求就会被限流。

二、限流方案

1、计数器

Java内部也可以通过原子类计数器AtomicInteger、Semaphore信号量来做简单的限流。

2、漏桶算法

漏桶算法思路很简单,我们把水比作请求,漏桶比作是系统处理能力极限,水先进入到漏桶里,漏桶里的水按一定速率流出,当流出的速率小于流入的速率时,由于漏桶容量有限,后续进入的水直接溢出(拒绝请求),以实现限流。

3、令牌桶算法

令牌桶算法的原理也比较简单,我们可以理解成医院的挂号看病,只有拿到号以后才可以进行诊病。

系统会维护一个令牌(token)桶,以一个恒定的速度往桶里放入令牌(token),这时如果有请求进来想要被处理,则需要先从桶里获取一个令牌(token),当桶里没有令牌(token)可取时,则该请求将被拒绝服务。令牌桶算法通过控制桶的容量、发放令牌的速率,来达到对请求的限制。

4、Redis + Lua

个人理解,Lua脚本和MySQL数据库的存储过程比较相似,他们执行一组命令,所有命令的执行要么全部成功或者失败,以此达到原子性。也可以把Lua脚本理解为,一段具有业务逻辑的代码块。

而Lua本身就是一种编程语言,虽然redis官方没有直接提供限流相应的API,但却支持了Lua脚本的功能,可以使用它实现复杂的令牌桶或漏桶算法,也是分布式系统中实现限流的主要方法之一。

相比Redis事务,Lua脚本的优点:

  • 减少网络开销:使用Lua脚本,无需向Redis发送多次请求,执行一次即可,减少网络传输。
  • 原子操作:Redis将整个Lua脚本作为一个命令执行,原子,无需担心并发。
  • 复用:Lua脚本一旦执行,会永久保存Redis中,其他客户端可复用。

Lua脚本大致逻辑如下:

  • 通过KEYS[1]获取传入的key参数。
  • 通过ARGV[1]获取传入的limit参数。
  • redis.call方法,从缓存中get和key相关的值,如果为null那么就返回0。
  • 接着判断缓存中记录的数值是否会大于限制大小,如果超出则表示该被限流,返回0。
  • 如果未超过,那么key的缓存值+1,并设置过期时间为1秒钟以后,并返回缓存值+1。

5、网关限流

限流常在网关这一层做,比如Nginx、Openresty、kong、zuul、Spring Cloud Geteway等,而像Spring Cloud Gateway网关限流底层的实现原理,就是基于Redis + Lua,通过内置Lua限流脚本的方式。

三、Redis + Lua 限流实现

下面通过 自定义注解aopRedis + Lua 实现限流。

1、环境准备

SpringBoot项目创建:https://start.spring.io,很方便实用的一个工具。

2、引入依赖包

pom文件中添加如下依赖包,比较关键的是spring-boot-starter-data-redis和spring-boot-starter-aop。

3、配置application.yml

在application.yml文件中配置提前搭建好的redis服务地址和端口。

4、配置RedisTemplate实例

限流类型枚举类

5、自定义注解

我们自定义一个@Limit注解,注解类型为ElementType.MEHTOD即作用于方法上。

period表示请求限制时间段,count表示在period这个时间段内允许放行请求的次数。limitType代表限流类型,可以根据IP、自定义key,如果不传limitType属性则默认用方法名作为默认key。

6、切面代码实现

7、控制层实现

将@Limit注解作用在需要进行限流的接口方法上,下边我们给方法设置@Limit注解,在10秒内允许放行三个请求,为了直观一点用AtomicInteger计数。

8、测试

注:因为适用了Lua编程语言,需要安装EmmyLua插件,大家自行百度,这里不做详细介绍了。

测试[预期]:10秒之内连续请求3次均可成功,第四次请求被拒绝。直接适用postman进行测试。


十秒之内,第4次请求时,应用直接决绝了请求,说明 SpringBoot + aop + Lua 限流方案搭建成功。

四、源码

git源码地址


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
LUA 字符串密码格式校验发布时间:2022-07-22
下一篇:
mac系统php5.6安装lua扩展遇到的问题解决发布时间:2022-07-22
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap