场景
目前开发的是一个4S店的小程序模板,其中有预约模块,即用户可以预约洗车、保养等项
目,若用户在预约的时候由于网络问题导致请求时间过长,可能会重复点击请求按钮,造成
同样的预约预约了两次,因此考虑到重复请求的问题。
Tip:其实写数据的操作感觉都需要处理重复请求,要不然总会操作一次DB。
思考方案
前端控制
逻辑
请求前,参数判断后,禁用按钮
请求回调的最后一步再启用按钮
问题
可以避免一部分的重复请求;
但如果极端一点,启用按钮后还是有一丢丢机会是可以再次发送同样请求的;
携带请求编号进行请求
步骤
1、进入页面时获取请求编号
2、写操作时,携带该请求编号才可以操作
方案一(个人想法)
步骤
1、获取请求编号
set key 0 ex nx:设置一个请求编号,值为0
2、写操作
获取key
key不为null则incr[自增1]
incr后的值为1,则表示可以操作
非1则表示重复请求的次数,如果次数达到一定量,则可对用户做些处理之类的
优点
一个请求编号只能用一次,因为是在获取编号时set进redis中;
不会出现方案二中过了key的超时时间后,该key又可以再次携带发送请求。
缺点
判断会比较多
方案二(常见方案,也算是方案一的简版)
步骤
1、获取请求编号
redis中incr一个key,请求编号 = REQ + 该key的值(因为incr是原子性的,所以不会
重复)
2、写操作
set key value ex nx
设置成功,则可以操作;失败则表示重复请求
优点
相比方案一,判断逻辑少,只有一个if
缺点
如果请求编号的过期时间到了,再次携带该编号还是可以请求(不过这种场景还没遇见
过)
根据参数来做唯一标识符
简述:该方案类似于请求编号中方案二,只不过编号是根据请求参数来生成的
步骤
将参数转换为JSON串
再将其MD5加密后作为key(要不然JSON可能太长)
后续步骤类似请求编号方案二
优点
不需要在请求前先获得请求编号,少了一次请求;
可以根据参数来配置key,这样即可以避免重复请求,但需要考虑好哪些参数能作为辨
别的参数
缺点
也是如果在过期时间到了后,也可以继续请求
其他
如果是通用的重复请求逻辑,则可以通过切面的方式,在切面中判断即可;
我在demo中的判断方式就是通过注解 + 切面的方式来判断重复请求。
小结
请求编号方案二和请求参数方案都算是比较常见的方案了,不过像请求编号方案一,虽然
逻辑胖了一些,但是他可以记录下重复请求的次数,可能会有一些用途,以上就是今天的
一些思考,虽然还没用在项目中,至少先知道有哪些方案也不错啦!
一个小demo,使用请看readme学习