当前位置:   article > 正文

秒杀项目遇到的问题&重难点&优化扩展【Java面试项目】

秒杀项目遇到的问题&重难点&优化扩展【Java面试项目】

前言

2023-7-26 14:38:09

2023-07-31 19:54:20

公开发布于
2024-5-20 13:14:37

以下内容源自《【Java面试项目】》
仅供学习交流使用

版权

禁止其他平台发布时删除以下此话
本文首次发布于CSDN平台
作者是CSDN@日星月云
博客主页是https://blog.csdn.net/qq_51625007
禁止其他平台发布时删除以上此话

项目遇到的问题

秒杀项目的总结及面试常见问题

Redis 远程连接失败【bug】

https://jsss-1.blog.csdn.net/article/details/128263725

配置文件的保护模式
以及绑定bind的地址

在这里插入图片描述

秒杀项目遇到的重难点

跨域的实现

后端的CORS方案

在这里插入图片描述
在这里插入图片描述

登录注册功能的实现

原来使用session存储

session:CSRF 攻击详解

CSRF(Cross Site Request Forgery,跨站域请求伪造),也被称为 “One Click Attack” 或者 Session Riding,通常缩写为 CSRF 或者 XSRF 。

在这里插入图片描述

在这里插入图片描述

后端:redis存储token

前端浏览器:session storage存储

请求的时候:token=" + sessionstorage.getItem( "token")

cookie和session及token,为什么选择使用token?JWT使用

「揭秘」Token与Session到底有何异同?

ROCKETMQ事务型消息

两阶段提交
保证消息的一致性
保证本地事务和消息的消费者的一致性
提交–消费
回滚–不消费

在这里插入图片描述

步骤:

1-4 :第一阶段
5,7 很长时间仍没结果得不到正确的执行,把半成品消息放到死信队列中,人工介入

  1. 生产者 send MQ Server 发送半成品消息
  2. ok 不会让消费者先消费这条消息
  3. 访问mysql执行本地事务
  4. 成功就commit,失败就rollback 是否允许消费者消费这条消息 第4步没有传递到Server,半成品消息一直消费不了
  5. 加入回查机制check 时间递增
  6. 服务器去check数据库
  7. 反馈结果给MQ
  8. 半成品消息转为正式消息,让消费者消费

代码需要体现1 3 6 步

解决超卖:异步化扣减库存

把商品并和库存表分开

下单时扣减内存,

因为有人不会付款,所以存在少买问题

付款的时候进行扣减库存:会存在超卖的问题,解决:实际库存大于预先库存

在15分钟之内进行付款

扣减库存
生成订单
更新销量
  • 1
  • 2
  • 3

在这里插入图片描述

步骤

  1. 生成流水,在发送消息之前。 流水为了更好的判断库存状态用于check
  2. 发送消息
  3. 预减库存(在缓存中),创建订单
  4. 更新流水
  5. check 检查流水
  6. 检查库存流水 锁的粒度比库存较小
  7. 最后扣减库存

下单操作:项目亮点

创建订单时在缓存中预减库存,性能高,并且解决超卖问题
预减库存和扣减库存是异步的
如何异步扣减库存
通过mq来实现
缓存中扣减还得最终保证在mysql中扣减库存,保证最终一致性
如何check
为什么创建流水
顺序插入速度快,锁粒度小
为什么流水在最前面生成
流水最前,这样就保证回查的时能查到流水的状态

秒杀项目遇到的优化扩展

订单表id

id设置成年月日开头+商品流水号

在这里插入图片描述

在这里插入图片描述

商品流水号:是for update,一致性读出来
在这里插入图片描述

解决少买问题

假如减了库存但用户没有支付,怎么将库存还原继续进行抢购

  • 订单超时未支付则删除订单,增加库存数量,恢复Redis缓存和本地缓存的数量
  • 但是对于秒杀项目之所以采用下订单减库存而不是付款减库存不就是因为秒杀商品秒到就是赚到大概率不会不付款嘛。另外即使不付款,那就不会发货,只会少卖不会超卖对于商户也不会有什么损失吧。
订单15分钟内付款

作废订单,回收库存

延时队列
消费检查
回补库存
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

缓存的问题:穿透,雪崩

布隆过滤器

不一样的缓存时间

接口如何限流防刷(验证码+通用拦截器限流)

思路:1.对接口做限流;2.将用户对接口的访问次数缓存在redis中;3.通过拦截器来进行
具体步骤:

  • 自定义一个AccessLimit注解,里面的参数是时间、最大访问次数以及是否需要登录;
  • 定义一个拦截器继承HandlerInterceptorAdapter类,再重写他的preHandle方法;
  • 使用@AccessLimit(seconds=5, maxCount=5, needLogin=true),规定单位时间内的最大访问次数。

隐藏秒杀接口

思路:秒杀开始之前,先去请求接口获取秒杀地址

1.接口改造,带上PathVasriable参数

2.添加生成地址的接口

3.秒杀收到请求,先验证PathVariable

注意事项:

1.虽然前端页面在秒杀未开始时秒杀按钮设置为不可用,但是有可能用户通过前端js代码找到秒杀地址在秒杀未开始时直接访问,秒杀接口隐藏的目的是用户通过js获取到的秒杀地址并不能让其完成秒杀功能

2.在秒杀之前要先通过Controller中的/path路径下的类随机生成一个path,然后和用户ID一起存入Redis,在执行秒杀的时候再从Redis中取Path进行验证,然后进行秒杀

阿里云短信验证码

短信验证码原来是输入到控制台的

添加了功能:阿里云短信验证码

最后

2023-7-31 19:48:56

我们都有光明的未来

祝大家考研上岸
祝大家工作顺利
祝大家得偿所愿
祝大家如愿以偿
点赞收藏关注哦

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/807329?site
推荐阅读
相关标签
  

闽ICP备14008679号