基本原理:RocketMQ的设计中broker与producer端的双向通信能力,使得broker天生可以作为一个事务协调者存在;而RocketMQ本身提供的存储机制<br>为事务消息提供了持久化能力;RocketMQ的高可用机制以及可靠消息设计则为事务消息在系统发生异常时依然能够保证达成事务的最终一致性。
<ul><li>普通商品下单链路分析</li></ul>
<ol><li>根据购物车信息生成订单后直接插入数据库中,同时锁定库存(ProductFeignApi)、删除购物车商品(CartFeignApi)、获取订单详情item的全局Id(unqidFeignApi)、设置收货地址和相关积分(UmsMemberFeignApi),这些需要分布式事务来保证(采取Seata的AT模式实现GlobalTransaction)</li></ol><br>
<br>
seata客户端配置
2.1前端请求支付二维码的同时,向rocketmq发送事务消息,该消息反向通知是否取消订单。rocketmq事务监听者在本地事务中只向Redis中记录回查次数 并返回UNKNOWN状态。 2.2事务回查时向支付宝请求订单支付状态,如果支付成功则删除redis记录、更新订单支付状态、扣减锁定库存并返回ROLLBACK状态,否则 回查次数+1返 回UNKNOWN状态。 2.3超过最大回查次数则更改订单状态为无效(即订单超时),返回COMMIT状态。<br>
2.1
2.2
3.订单消息消费者收到取消订单的消息后,调用ProductFeignApi恢复真实库存、扣减锁定库存。<br>
<ul><li>秒杀商品下单链路分析</li></ul>
<ol><li>返回秒杀订单确认信息前,需要提前从分布式唯一Id微服务(unqidFeignApi)获取order_id和order_Item_Id并存入本地缓存,如果获取不到足够的Id则不允许用户下单。</li></ol><br>
2.校验是否有权限购买商品,从redis取出当前要购买的商品库存和下单排队状态,如果售罄了在本地cache中标记状态,否则,继续检查是否用户在上个商品 还未下单完成又重复购买,这些情况则返回失败信息,禁止用户购买。<br>
3.验证秒杀时间是否超时、获取用户收货地址、计算订单总金额,完成秒杀信息确认单<br>
4.秒杀商品下单,采用redis缓存中直接扣减库存,结合RocksDB本地数据库快速持久化扣减记录来应对redis宕机的情况<br>
5.向Rocketmq发送异步下单消息,如果发送失败需要还原预减库存、清除本地售罄标记缓存、向redis发布相关channel信息<br>
6.创建秒杀订单Topic下的消费者收到消息后,开始扣减库存(promotionFeignApi),向订单表中插入订单记录和关联信息,继续向mq发送订单超时取消的消 息(延迟消息),根据是否发送成功更改redis中订单排队标记。<br>
7.前端开始轮询订单状态,如果订单排队标记>1则代表下单成功跳转到支付页面,否则秒杀失败返回重试。<br>
8.用户进入支付页面,准备扫描支付宝二维码支付订单。
9.延迟时间结束,取消订单消息的订阅者收到消息则开始检查订单支付状态,如果为未付款status则恢复促销商品数量(PromotionFeignApi)和redis库存<br>