本文主要讲解基于 自定义注解+Aop+反射+Redis+Lua表达式 实现的限流设计方案。实现的限流设计与实际使用。
1.背景在互联网开发中经常遇到需要限流的场景一般分为两种
业务场景需要(比如:5分钟内发送验证码不超过xxx次); 对流量大的功能流量削峰;一般我们衡量系统处理能力的指标是每秒的QPS或者TPS,假设系统每秒的流量阈值是2000, 理论上第2001个请求进来时,那么这个请求就需要被限流。
本文演示项目使用的是 SpringBoot 项目,项目构建以及其他配置,这里不做演示。文末附限流Demo源码
2.Redis计数器限流设计本文演示项目使用的是 SpringBoot 项目,这里仅挑选了重点实现代码展示, 项目构建以及其他配置,这里不做演示,详细配置请参考源码demo工程。
2.1Lua脚本Lua 是一种轻量小巧的脚本语言可以理解为就是一组命令。 使用Redis的计数器达到限流的效果,表面上Redis自带命令多个组合也可以支持了,那为什么还要用Lua呢? 因为要保证原子性,这也是使用redis+Lua表达式原因,一组命令要么全成功,要么全失败。 相比Redis事务,Lua脚本的优点:
减少网络开销:多个请求通过脚本一次发送,减少网络延迟 原子操作:将脚本作为一个整体执行,中间不会插入其他命令,无需使用事务 复用:客户端发送的脚本永久存在redis中,其他客户端可以复用脚本 可嵌入性:可嵌入JAVA,C#等多种编程语言,支持不同操作系统跨平台交互实现限流Lua脚本示例
参数说明
KEYS[1] - redis的Key ARGV[1] - 限流次数 ARGV[2] - 失效时间 2.2自定义注解支持范围:任意接口
属性介绍
key - 必填,限流key唯一标识,redis存储key time -过期时间,单位 秒,默认60s count - 必填,失效时间段内最大放行次数 keyField - 动态限流key,比如参数是一个自定义的类,里面有属性userId 等。可以使用keyField=“userId”,这样生成的key为参数中userId的值。一般与key属性组合使用。不支持java基本类型参数, 仅支持参数是一个对象的接口。
msg - 超过限流的提示内容
示例:
含义 - 5分钟内根据手机号限流10次 RedisKey- limit-phone-key:后面拼接的是参数中phone的值。
2.3限流组件这里用的是jedis客户端,配置就不列在这里的,详见源码,文末附源码地址
2.4限流切面实现由于演示项目中做了统一异常处理 在限流切面这里未做异常捕获,若超过最大限流次数会抛出自定义限流异常。可以根据业务自行处理。
3.测试一下基本属性已经配置好了,写个接口测试一下。
3.1方法限流示例 3.2动态入参限流示例3.2.1场景一:5分钟内,方法最多访问10次,根据入参手机号限流
入参类
3.2.2场景二:根据订单ID限流
入参类
4.其它扩展根据ip限流
在key中拼接IP即可;
5.源码地址传送门
到此这篇关于Redis分布式限流组件设计与使用实例的文章就介绍到这了,更多相关Redis分布式限流内容请搜索七叶笔记以前的文章或继续浏览下面的相关文章希望大家以后多多支持七叶笔记!