前言
注:
大家好我是妈妈的好大儿,
笔者联系方式
QQ:3302254385
微信:yxc3302254385
交个朋友!
创作不易,三连十分感谢!!!
封装缘由
各位小伙伴们大家好!!,在平常的编写接口的过程中,一般都会遇到一个问题就是说关于我们接口限速的,如
- 同一用户恶意调用同一接口,导致接口压力过大
- 用户频繁提交的问题,有些操作是不必要的,所以我们需要对同一用户进行接口限速!!!
当然在我们整合第三方服务,如高德地图,微信小程序等等一些服务时,别人对接口的调用也做了限制如每日的调用次数,或者说QPS意思是接口每秒的响应效率等 因为设计到成本的问题,毕竟有钱就能使你变强,马爸爸说的,可不关我的事,当然实现方法有很多种,看具体的业务场景,此博文只提供一种思路或者一种实现方式!
项目实际需求点
项目是一个基于微信小程序,为一个音乐节的前期宣传推广而开发的,存在用户给选手投票,但是每个用户的投票次数都是有次数限制的,大家也知道平常我们点赞的时候会连续点击,有些时候我们没有票数了,用户还在点击(可以通过前端限制解决),或者说用户直接拿到了我们接口的URL地址直接进行访问刷新会导致很多问题!!!!
需要掌握的知识点
springBoot,Redis,AOP,注解和反射,异常
不会也没关系,注释很详细可以当入门看
封装思路
- 通过注解标识我们的接口,对于同一用户的次数限制,限制时长区间是多少,快速使用接口的限速,实现快速可拔插的效果,特别方便
- 有了注解,我们肯定需要Handle去处理,标识过的此注解的接口
- 如果用户的访问次数超过我们的限制,抛出了异常需要手动捕获吗?当然这样是很麻烦的!我们可以使用自定义异常,和Spring提供的AOP和注解来实现异常中心捕获我们的自定义异常!
上代码
1.首先定义我们的注解,用于标注在我们的接口之上,代表需要增强的接口
/**
* 创建
* ip拦截器 注解
* @author cc
* @date 2020-06-26-9:36
*/
//元注解--->注解信息保留到class文件运行仍可获取
@Retention(RetentionPolicy.RUNTIME)
//元注解--->只能使用在我们的方法之上
@Target(ElementType.METHOD)
//元注解--->JavaDoc会生成此枚举的文档
@Documented
public @interface IpInterceptor {
/**
* @Description: 限制某时间段内可以访问的次数 (默认设置100)
* @return
*/
long requestCounts() default 100;
/**
* @Description: 限制访问的某一个时间段,单位为秒 (默认值1分钟即可)
* @return
*/
int expiresTimeSecond() default 60;
/**
* @Description:
* 接口是否是restful风格 (默认false)--->因为Restful风格请求参数是直接跟在请求地址后,由于每次传递的参数不同也会导致,也就无法判断真正的请求地址,由此需要标注
*
* @return
*/
boolean isRestful() default false;
/**
* @Description: restful风格参数个数 (默认0),用于restful风格请求地址的解析
* @return
*/
int restfulParamCounts() default 0;
}
2.注解的处理器 —>注解功能的具体实现
/**
* 创建
* IpInterceptor ip拦截器具体实现
* @author cc
* @date 2021-02-26-10:46
*/
//自定义类 切面
@Aspect
//注入Spring
@Component
@Slf4j
public class IpInterceptorImpl {
@Autowired
private RedisUtil redisUtil;
@Autowired
@Qualifier("myRedisTemplate")
private RedisTemplate<String, Object> redisTemplate;
//方法前置增强--->增强标注过IpInterceptor注解的方法
@Before("@annotation(com.cc.util.IpInterceptor)")
public void requestLimit(JoinPoint joinPoint