Redis防重机制

举报
yk02901 发表于 2021/05/07 15:25:39 2021/05/07
【摘要】 使用防重复机制的背景1.由于用户误操作,多次点击表单提交按钮。2.由于网速等原因造成页面卡顿,用户重复刷新提交页面。3.黑客或恶意用户使用postman等工具重复恶意提交表单(攻击网站)。这些情况都会导致表单重复提交,造成数据重复,增加服务器负载,严重甚至会造成服务器宕机。因此有效防止表单重复提交有一定的必要性。解决方案针对目前比较流行的分布式系统,结合在项目实施过程中遇到的问题,以及在解决...
使用防重复机制的背景
1.由于用户误操作,多次点击表单提交按钮。
2.由于网速等原因造成页面卡顿,用户重复刷新提交页面。
3.黑客或恶意用户使用postman等工具重复恶意提交表单(攻击网站)。
这些情况都会导致表单重复提交,造成数据重复,增加服务器负载,严重甚至会造成服务器宕机。因此有效防止表单重复提交有一定的必要性。
解决方案
针对目前比较流行的分布式系统,结合在项目实施过程中遇到的问题,以及在解决问题中总结的经验,我大致总结了几种方案,以及各自的优缺点,仅供大家参考。
1.通过前端控制:
具体做法:用户点击提交按钮之后,就把提交按钮置灰不可用,直到交易收到发馈之后,再把提交按钮设置成可用状态。
该方案优点:修改前端按钮,不修改具体业务逻辑,修改简便,易于理解。
缺点:该方案用户可以通过刷新页面方式、使用postman等工具可以绕过前端页面仍然可以重复提交。该种方案不推荐
2.数据库添加唯一索引:
具体做法:在数据库建表的时候在id字段添加唯一索引,例如:用户名称、联系方式、电子邮箱等字段添加唯一约束,通过该种方式保证数据库数据唯一和有效性。后端代码针对插入数据操作的方法,加入捕获异常的方式,避免数据库重复插入相同的数据。
该方案的优点:简单、易于理解。
缺点:如果在项目后期,修改数据库表的结果,可能影响比较大;该方案无法阻止恶意的网站攻击,服务器会出现大量的sql语句插入,增加服务器和数据库的负荷。
3.使用session防重复提交:
具体做法:在服务端生成一个唯一的随机编号,可以称之为Token,然后在当前用户的session域中保存这个Token。然后将这个Token发送到客户端的Form表单中,表单提交时候连同这个Token一起提交到服务端,服务端判断上送过来的Token是否和服务器生成的一致,如果不一致就是重复提交的数据,服务端就不再处理提交的数据。如果相同则处理,处理完成之后清理掉Session域中存储的随机编号。
我们项目实施初期一开始使用的是该种方案,在实施过程中发现存在缺点:
每次提交动作前都先发送一次请求,获取唯一编号,前端提交类交易比较多,方案改动量比较大,可用性差。而且后端改造会侵入具体的业务逻辑,也不推荐该种方案。
针对以上几种方案存在的问题,分布式系统推出了使用Redis,针对项目用遇到的问题,我和大家分享下自己对redis防重的一些理解和经验。
Redis技术解决防重复提交
关于重复请求,指的是我们服务端接收到很短的时间内的多个相同内容的重复请求。而这样的重复请求如果是幂等的(每次请求的结果都相同,如查询请求),那其实对于我们没有什么影响,但如果是非幂等的(每次请求都会对关键数据造成影响,如删除关系、建立关系等),那就会轻则产生脏数据,重则导致系统错误。
因此,在当前普遍分布式服务的情况下,如何避免和解决重复请求给我们带来的数据异常成为了亟待解决的问题。而避免重复请求,最好的做法是前后端共同去做。
1. 前端或客户端在非幂等的按钮上直接做禁止提交重复请求的操作。
2. 后端在接收到请求时加锁,完成后解锁,使用redis锁来实现
为何要使用分布式锁来解决呢?因为我们当前普遍的架构都是分布式的服务端,前端请求通过网关层转发至后端。
如下图所示,因此如果只在一个单独的服务器上做限制,就无法在分布式的服务中完成应对高频次的重复请求了。
【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。