主题
面试速答(先看这里)
**一句话结论:**1、首先就是前端需要做一些按钮置灰的动作,让用户点击一次之后,按钮就直接禁用调,让用户无法重复点击。
60秒标准回答:
当不让使用redis分布式锁,或者集群不可用的时候,如何做到防止用户重复点击的功能呢?
有以下几个思路可以供大家参考
1、首先就是前端需要做一些按钮置灰的动作,让用户点击一次之后,按钮就直接禁用调,让用户无法重复点击。但是有些情况可能没来得及置灰就重复点击了,或者有些用户自己绕过了置灰也可以点击
**答题顺序:**结论 → 原理/机制 → 关键流程 → 场景与取舍 → 易错点
回答主线:
- **要点1:**当不让使用redis分布式锁,或者集群不可用的时候,如何做到防止用户重复点击的功能呢?
- **要点2:**2、可以通过token的机制避免重复提交,当用户访问页面的时候,请求后端服务拿到一个token,然后下一次接口点击的时候把token带过来,服务端对token进行验证,验证该token是否被使用过,如果没有被使用过才可以进行点击。
- **要点3:**比如,以下就是我自己的 高并发实战项目 中,通过token来进行订单防重复的一个具体的交互图:
- **要点4:**3、滑动窗口限流,滑动窗口限流是一种流量控制策略,用于控制在一定时间内允许执行的操作数量或请求频率。
- **要点5:**5、还有种方式,那就是参考 ruoyi 框架中的防重复提交的实现方案,其实就是把表单信息做校验并保存在 REDIS 中,下次再提交的时候做校验,如果和上次提交的内容一样,并且时间小于一定的时间间隔,则拒绝请求,
**记忆锚点:**token → redis → 不用redis分布式锁 → 个元素是否存在于集合 → 通过数据库的悲观锁 → fail-fast
关键取舍:
- 我们可以限制一分钟或者一秒钟内用户只能发起一次请求来防止重复点击。
易错提醒:
- 2、可以通过token的机制避免重复提交,当用户访问页面的时候,请求后端服务拿到一个token,然后下一次接口点击的时候把token带过来,服务端对token进行验证,验证该token是否被使用过,如果没有被使用过才可以进行点击。
加分表达:
- 如果布隆过滤器不存在,则一定不存在,所以,如果没查到,说明一定没有幂等操作,直接执行就行了。
- 如果查询布隆过滤器发现有命中,则需要在服务数据库做一次幂等判断。
追问准备:
- 围绕「token」:底层原理是什么?使用时有哪些边界和常见坑?
- 围绕「redis」:底层原理是什么?使用时有哪些边界和常见坑?
- 围绕「不用redis分布式锁」:底层原理是什么?使用时有哪些边界和常见坑?
- 如果线上出现异常,你会如何定位、验证并规避?
典型回答
当不让使用redis分布式锁,或者集群不可用的时候,如何做到防止用户重复点击的功能呢?
有以下几个思路可以供大家参考:
1、首先就是前端需要做一些按钮置灰的动作,让用户点击一次之后,按钮就直接禁用调,让用户无法重复点击。但是有些情况可能没来得及置灰就重复点击了,或者有些用户自己绕过了置灰也可以点击。
2、可以通过token的机制避免重复提交,当用户访问页面的时候,请求后端服务拿到一个token,然后下一次接口点击的时候把token带过来,服务端对token进行验证,验证该token是否被使用过,如果没有被使用过才可以进行点击。验证的逻辑可以放在数据库中,通过数据库的悲观锁或者乐观锁都可以实现。
📄 ✅Cookie,Session,Token的区别是什么?
打开文档:✅Cookie,Session,Token的区别是什么?
比如,以下就是我自己的高并发实战项目中,通过token来进行订单防重复的一个具体的交互图:
3、滑动窗口限流,滑动窗口限流是一种流量控制策略,用于控制在一定时间内允许执行的操作数量或请求频率。我们可以限制一分钟或者一秒钟内用户只能发起一次请求来防止重复点击。
4、可以使用布隆过滤器,他可以快速判断某个元素是否存在于集合中。可以在服务器端使用布隆过滤器记录某个操作是否已经被执行过,从而防止重复执行。
> 如果布隆过滤器不存在,则一定不存在,所以,如果没查到,说明一定没有幂等操作,直接执行就行了。 > > 如果查询布隆过滤器发现有命中,则需要在服务数据库做一次幂等判断。 > > 大多数情况下,需要幂等的情况占比小,所以可以用布隆过滤器做一次fail-fast的快速校验。
Redis其实也是一个集中式的存储服务,在特殊情况下,如果无法使用,一般的做法都是降级成直接使用数据库。
5、还有种方式,那就是参考 ruoyi 框架中的防重复提交的实现方案,其实就是把表单信息做校验并保存在 REDIS 中,下次再提交的时候做校验,如果和上次提交的内容一样,并且时间小于一定的时间间隔,则拒绝请求,