前言
近期接到开发任务,需要以图书为中心开发一套书籍在线商城系统,由于之前没有做过相关的系统,借此机会梳理总结一下各个模块的处理逻辑。
简易实现,项目开发中,有更好的想法请指教。
购物车需求
购物车包含以下需求:
- 购物车查看
- 选中/取消商品
- 加入购物车/立即购买
- 删除商品
- 修改商品数量
- 购物车商品数量
促销
以上是购物车的一般需求(促销目前没有涉及),针对于用户的一些需求。
购物车需求分析
购物车查询
购物车操作相较为频繁,传统的存入数据库的方式不能满足处理速度需求。此时转为了缓存方式存储,也就是使用Redis
的方式存储购物车的相关信息。
简易购物车把有关于商品的信息都存储到了缓存,查询时直接返回用下的购物车缓存即可。
存储信息如下:
- 商品信息。ID、名称、状态、缩略图、价格、套餐属性。
- 选中状态。
- 商品数量。
当我们引入缓存时,引申出另外的问题:
- 如何保证缓存中的数据不丢失。
- 如何保证缓存中的数据与数据库保持一致,例如商品下架等情况。
解决方案:
Redis
采用集群部署,避免其中有Redis
宕机造成数据丢失。- 加入购物车时,校验此商品的有效性,当发现加入商品出现过期下架的情况,触发更新整个购物车逻辑。
- 在提交订单后,触发更新购物车逻辑。
ps:这样并不能实时的查询出有效的商品,仅有发现购物车存在失效商品后,才会触发更新操作。
后续解决方案:
- 当我们修改商品信息的时候,把一个标记存入缓存,记录此时的时间。
- 当用户查询购物车时,根据购物车的时间标记与上述标记对比进行购物车的同步,已达到缓存与数据一致。
选中/取消
此功能有两种实现方式:客户端、服务端。
客户端:
优点:
- 每次操作不需要调用服务端,能够减少性能损耗,减少网络请求。
- 客户端操作,不需要开发单独的接口实现。
缺点:
- 不能多端同步,显示不一致。
服务端:
优点:
- 能够实现多端同步。
- 商品价格计算可以同步返回,不需要客户端计算。
缺点:
- 每次操作都需要发送请求,网络开销大。
个人感觉这两种方案都是可以的,目前使用的是客户端进行存储操作。
相应的商品总价在提交订单时,服务端会对此金额进行验价,如果校验不通过会触发更新购物车操作,使前后台商品金额一致。
加入购物车/立即购买
加入购物车:商品 -> 购物车 -> 提交订单 -> 生成订单
立即购买:商品 -> 虚拟购物车 -> 提交订单 -> 生成订单
相比加入购物车和立即购买,前者是加入购物车,从购物车确认订单。后者是直接进入确认订单页面。
逻辑上相比,多了一步购物车的逻辑,其实也可以归为一类,给立即购买加入一个隐形购物车,此购物车只能存储一个商品,每次都会顶替掉上一个商品。
这样方便于后续的处理,逻辑可以公用。
商品状态
当我们把商品加入购物车过了很长时间后,有些商品会失效,后台已经不存在此商品,这时候需要把这部分商品在购物车中标识出来,并且不能参与结算。
后续查询MongoDB方案中,可以避免修改后延迟问题。
并发问题
购物车的最终结果是生成订单,在这其间有商品正确性校验、库存校验、金额校验、地址、发票等等信息进行处理,随着逻辑的边长时间也会相应边长。
这里需要使用分布式锁限制并发问题,多端时,当一端进行提交订单,其他的端不允许进行计算操作,避免下单出现问题。