这是道面试题,想不懂,请教大家

这是道面试题,请教大家

有 web 架构, NGINX + PHP-FPM + MYSQL, 利用 NGINX 实现负载均衡,MYSQL 实现主从分离
现发现评论表有如下数据

UserID Comment Created
10001 东西很棒! 2020-09-02 11:00:00
10002 非常满意 2020-09-02 11:00:00
10002 非常满意 2020-09-02 11:00:00
10003 下次还会再买 2020-09-02 11:00:05

请分析下可能产生的原因

==========分割线============
2020-12-11
这是中高级PHP的最后一道笔试题,接口重复提交肯定是原因,但也就只能是这种水平。
web架构会因什么原因造成数据重复,这应该才是面试官想要你答的

本作品采用《CC 协议》,转载必须注明作者和本文链接
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 25
orange1994

甩锅前端,没有做重复点击限制。

2个月前 评论
derek778 2个月前
wanzi 2个月前
Derek 2个月前
Celaraze 2个月前

可能原因:

1、前端表单数据重复提交。
2、接口没有做幂等设计。
3、对数据库的插入操作有重试逻辑。
4、多台设备操作同一个账号,产生的并发问题。

解决方法:

1、前端对表单做防止重复提交的限制、对提交表单做验证码限制。
2、对接口做幂等限制、对接口做频次限制 (允许多久提交一次)3、取消对数据库的重试逻辑,插入失败不再重试。
4、限制账号单点登录。

欢迎补充或指正

2个月前 评论
秦晓武 2个月前
pi_phq 2个月前
秦晓武 2个月前

MySQL 实现了主从读写分离,存在网络原因或其他原因,导致主从同步延迟,最终导致主库数据插入成功,而从库未及时同步数据,造成用户以为没有提交成功而重复提交或造成程序中判断异常进行了重复插入。
Created 时间是相同的,所以可能是因为后者,主从同步延迟导致程序中判断异常出现重复插入的情况

2个月前 评论

mark

2个月前 评论

抛砖引玉 userId非primary key非unique,客户端在2020-09-02 11:00:00发送了两次请求 有没有更靠谱的说法

2个月前 评论
bohe0723 2个月前
惊风破浪 2个月前
orange1994

甩锅前端,没有做重复点击限制。

2个月前 评论
derek778 2个月前
wanzi 2个月前
Derek 2个月前
Celaraze 2个月前
小烦

加个锁呗,插入操作前上锁并判断是否存在锁,结束时解锁。

2个月前 评论
runningcoder 2个月前
哓东 2个月前
runningcoder 2个月前
哓东 2个月前
哓东 2个月前
runningcoder 2个月前
哓东 2个月前
runningcoder 2个月前
  1. 前端没有做好禁止重复点击
  2. 评论表可以加个用户id和时间联合唯一约束
  3. 后端可以从提交时间做个限制
  4. 表单 token
    应该还有其他的方案,期待大神补充
2个月前 评论
yxhsea 2个月前
codemonkey 2个月前
Antony495 2个月前
konghou 2个月前

像评论这种接口肯定要做「防重放」。

2个月前 评论
Hugh

表单重复提交的问题

2个月前 评论
huangfsd (楼主) 2个月前
da_house

加锁

2个月前 评论

可能原因:

1、前端表单数据重复提交。
2、接口没有做幂等设计。
3、对数据库的插入操作有重试逻辑。
4、多台设备操作同一个账号,产生的并发问题。

解决方法:

1、前端对表单做防止重复提交的限制、对提交表单做验证码限制。
2、对接口做幂等限制、对接口做频次限制 (允许多久提交一次)3、取消对数据库的重试逻辑,插入失败不再重试。
4、限制账号单点登录。

欢迎补充或指正

2个月前 评论
秦晓武 2个月前
pi_phq 2个月前
秦晓武 2个月前

既然是中高级面试题,那考察的就不会是那些基础的幂等性如何实现,应该从架构设计方向去想,我觉得题中的很多关键词大家都忽略了,比如 Nginx的负载均衡、MySQL 的主从复制,我不清楚这两项如果在某种特殊的配置条件下是否会导致请求重复处理或者重复保存,进而出现这个结果,抛转引玉希望有真大佬来给一些提示。

2个月前 评论

MySQL 实现了主从读写分离,存在网络原因或其他原因,导致主从同步延迟,最终导致主库数据插入成功,而从库未及时同步数据,造成用户以为没有提交成功而重复提交或造成程序中判断异常进行了重复插入。
Created 时间是相同的,所以可能是因为后者,主从同步延迟导致程序中判断异常出现重复插入的情况

2个月前 评论

排除业务场景,单看解决问题,不知道锁表有没有用?

2个月前 评论
pi_phq 2个月前
aruisi

这个就是分布式,主从延时导致的并发问题,,应该从nginx负载 和主从同步误差方面解决,不过得先问一下nginx负载做的是哪一种

2个月前 评论
Fx 2个月前

是因为前端提交了两次,nginx负载均衡的转发,然后导致mysql两次请求的两个事务并发,写入了相同数据

2个月前 评论
aruisi

看到两个1002没有

2个月前 评论

是主从分离还是读写分离?

2个月前 评论
惊风破浪 2个月前

当数据量大读写分离有毛用

2个月前 评论
终生学习者

这个问题居然跑这里来了。。。。www.zhihu.com/question/434311322/a...

2个月前 评论
huangfsd (楼主) 2个月前

答案可能是这个 blog.51cto.com/fengwan/2461291

2个月前 评论
huangfsd (楼主) 2个月前

自己动手实战就行了,光讨论只是纸上得来终觉浅

2个月前 评论

我觉得考查的应该是 api 做好幂等
我一般会把 post, put,delete 的请求数据用 redissadd 去把请求了一次的数据存起来,比如我给 redis 这个key 设置有效期时间为1秒,那么一秒内 sadd 插入不了相同的请求数据

1个月前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!