1.画一下项目的架构图
略
2.项目可改进的地方
- 对于数据的动静分离没有做的很彻底,只是用到了浏览器缓存,没有使用CDN等技术
- 没有设置降级的方案
- 限流做的不够完善,目前只对用户对于某个商品的访问做了限流,没有对整体的流量做限流,比如不法分子有非常多的账号,同时对一个商品发起请求可能造成我们的服务不可用。
- 没有考虑redis穿透的情况处理方案
- 在这个项目中是对库存和静态数据进行了预热,但是实际中有可能某个商品可能一时间快速爆火,如果没有对这些是商品数据进行预热可能会使服务宕掉,需要快速发现热点数据的发现与隔离,比如某明星粉丝约定某一时刻购买某粉丝代言的产品,虽然该商品没有参加秒杀活动,但那一时刻也胜似秒杀
- 对于部署还没有进行实际的操练和学习,可以使用Ngnix做负载均衡
3.讲一下秒杀流程
- 用户在秒杀商品详情页面点击秒杀按钮
- 向服务器端请求秒杀路径,主要逻辑为生成随机path值存入redis中,根据此path值拼凑秒杀路径。
- 访问拼凑的秒杀路径,先验证路径中path是否在redis中存在,如果不存在直接返回错误。
- 利用本地缓存,redis缓存做预减库存对请求做分层过滤
- 在一个事务中完成减库存下订单的过程
4. 分布式Session是怎么实现的
- 用户登录后生成随机字符串,并向cookie中写入此字符串。
- 在Redis中记录此字符串和用户信息的映射
- 当用户再次访问网页时,取出cookie中对应字段值,根据此字段值访问Redis得到用户相关信息
5.如何解决超卖?
- 超卖问题主要依靠MySQL中排它锁实现的
- 在减库存时设置sql语句where中stock>0
6.如何解决重复下单?
- 执行减库存下订单逻辑前,判断是否在订单表中含有用户秒杀此商品的记录
- 利用唯一索引,在订单表中创建user_id和good_id组成的唯一索引,这样在重复插入数据的时候会插入失败,之前的减库存操作在事务中也会回滚。
7. 如何防刷?
- 对一个商品秒杀时Redis会记录一个用户对一个商品的秒杀按钮的点击次数,如果用户对按钮点击次数超过5次直接返回多次请求提示
- 但是并没有对所有流量进行限流(具体见项目的不足第二条)
8. 消息队列的作用?
- 削峰,减少同一时刻并发量
- 入队后直接返回用户排队中消息,提高用户体验
9. 压测?
- JMeter压测
- 10个线程一秒5000并发量,未优化前1300QPS,优化后2100QPS
- 虚拟机4核4G,未实际部署
10. 库存预减用的是哪个redis方法?
- 使用Jedis封装相关方法,减库存使用decr方法
11. 缓存和数据库数据一致性如何保证?
- 对于库存数据不需要保证,缓存中的库存只为了过滤请求,即使多放进来一些请求我们也可以在数据库层面保证不超卖。
- 对于商品信息的静态数据也不需要保证数据一致性,因为不会变
12. 如果项目中的redis服务挂掉,如何减轻数据库的压力
- 设置本地缓存
- 设置限流降级功能
- 做好参数校验
13. 假如减了库存但用户没有支付,怎么将库存还原继续进行抢购
- 订单超时未支付则删除订单,增加库存数量,恢复Redis缓存和本地缓存的数量
- 但是对于秒杀项目之所以采用下订单减库存而不是付款减库存不就是因为秒杀商品秒到就是赚到大概率不会不付款嘛。另外即使不付款,那就不会发货,只会少卖不会超卖对于商户也不会有什么损失吧。
14. 系统瓶颈在哪?
- 数据库
- 服务端网络,CPU和内存等硬件资源
- 对于服务端网络带宽可以向isp购买,服务器端硬件资源的话可以尽可能的加
- 另外可以减少耗费CPU和内存的操作,比如编码操作,序列化操作,频繁创建大对象的操作,防止出现内存泄漏
- 以上可以通过查看服务器运行时资源占用情况判断。
15. 如何再优化?
- 彻底的动静分离上CDN
- 可以考虑把第二条的东西说说吧
- 我不知道了啊。。。
16. 项目难点及问题解决?
- 数据一致性:防止超卖和重复下单
- 如何应对高并发:你懂得
- 如何保持高可用:你懂得
- 接口防刷
17.秒杀接口隐藏问题
- 用户点击按钮时首先请求一个路径,之后在拼接该路径完成真正的秒杀请求
- 用户可以知道获取path的url并发出请求,但是如果不对路径进行拼接就不会发出秒杀请求。
https://www.cnblogs.com/wyq178/p/11261711.html
https://zhuanlan.zhihu.com/p/59944775