单线程

四季春风,不厌冬

  1. 普通下单
  2. 异步下单
    1. 异步方案
      1. 异步线程
      2. 消息队列

普通下单

  下单扣减积分、余额等步骤都是链式行为,属于同步操作,当前行为异常,则整体失败,即下单失败;只有当所有操作都正常执行,订单记录生成,即下单成功。
普通下单流程.png(图中第二个“扣减积分”实为“扣减余额”)

  同步下单会降低系统的QPS,不利于高并发的场景。

异步下单

  订单接收下单请求,先在数据库插入订单记录,将其标记为“初始化”状态。下单扣减积分、余额等步骤均为异步操作,当且仅当所有操作结果返回成功,则更新订单记录为“有效”状态,否则置为“无效”状态。
异步下单流程.png

  异步下单省去了众多等待的时间,将会提升系统QPS,但是也面临着业务领域模型变更和技术实现上的挑战。

异步方案

异步线程

  当订单服务完成订单记录插入后,开启若干异步线程对积分、余额服务发起扣减请求,直到积分、余额都扣减成功,则该订单才生效。

  若返回部分成功部分失败,则对返回成功的服务发起回滚请求。为了避免超时等待线程的情况,可以设置等待时间,如果超时则发起回滚请求。

消息队列

  当订单服务完成订单记录插入后,将下单消息push给消息中间件,积分、余额服务等消费方poll消息进行消费,根据消息内容扣减相应的额度,并回调订单服务。

  消息队列实现代价很高,主要原因如下:

  • 业务领域模型变更
      消息列队使订单与其他系统解耦,同时也变更了业务领域模型:扣减积分、余额、库存等操作是由订单主动发起,积分、余额、库存系统等提供者作为底层服务不关心上层业务。但是通过消息传播之后,积分、余额、库存需要解析数据,根据业务进行相应的扣减,此时的订单成为了底层服务,积分、余额、库存成为了业务方。角色的定位直接影响服务和团队的业务走向。

  • 消息安全性
      这里的安全性指的是消息丢失、幂等、收集消费结果问题。这些都极大地增加了双方的开发、维护成本,特别是 如何收集同一个topic的多方消费结果。

本文作者 : pengqin.zhou
本文使用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 协议
本文链接 : https://www.zhoupq.com/blog/%E5%BC%82%E6%AD%A5%E4%B8%8B%E5%8D%95%E8%AF%95%E6%83%B3/

本文最后更新于 天前,文中所描述的信息可能已发生改变