业务
电商系统三大黄金链路为:采购、购物、退货流程。每一个流程都牵涉了大量的分布式服务之间调用,以下是一个简单采购流程的模拟业务:
其可以分为颜色不同标记的三部分:采购入库、采购入库单审核、采购结算单审核。
技术
1.分布式微服务调用
2.分布式接口幂等性保障
2.1 幂等性保障常见方案:
分布式系统幂等性常见方案见:https://segmentfault.com/a/1190000037546272
2.2 幂等性在电商使用
2.2.1 采购入库
创建采购单:
创建采购单是采购人员通过前端创建,采购审核人员审核,如果创建多个只需要通知下采购审核人员即可,不需要幂等性保障。
提交审核:
提交审核针对于编辑中的采购单进行提交审核,如果采购单审核了,那么根据业务状态机可满足幂等性
审核采购单:
采购中心:审核的是待审核的采购单,审核会更改其状态,所以已经保障幂等性。
调度中心:调度中心只是基于内存转换,没有设计到数据存储等操作,幂等性不用管。
wms中心:创建采购入库单涉及到spring cloud的服务之间的重试调用,服务之间的调用,其实可能确实还是会遇到一些重复性的一些问题的,可能服务间的网络超时了,重复调用,重复采购入库单,重复了,那就不是那么回事了。此时需要使用业务表唯一索引:请求唯一标识采购单id作为唯一表索引。重复创建订单,触发事务回滚。
采购中心:wms通知采购中心采购入库单已经创建,采购中心更改采购单状态时候,使用状态机模式
2.2.2 采购入库单审核
审核人员直接通过页面操作wms中心进行商品审核.
wms中心:待审核的采购入库单才能审核,状态机模式即可。
采购中心:采购中心待入库变成已入库;状态机。注意:采购入库完之后,需要进行wms本地更改库存,然后调度中心才会同步调度更改库存,由于采购审核和本地库存更新是一个接口内,所以保证采购状态只执行一次,既可以保证状态更改幂等性,也可以保证本地库存更新幂等性,所以这里需要做额外处理:
逻辑如下:
void approve(purchaseInputOrderId,result){
//1.根据id查询采购单状态。
//2.根据采购单状态如果不是“待审核”状态,直接返回。
//3.待审核状态,更改采购单状态为“已入库”。然后更改本地库存,通知其他中心。
}
调度中心:通知调度中心,wms采购入库已经完成,wms中心已经获取到物流发过来的商品,然后通知调度中心更改“商品sku”库存,库存表里面没有状态且更改库存是update操作,不是insert操作,所以业务表内唯一性不可用,这个时候,添加额外一张mysql去重表(主键为:请求唯一标识:采购入库单id)
库存中心:库存中心一般不会跟wms直接调用,都是调度中心做同步;此时存在分布式接口调用重试,需要保证库存中心的库存,同理,库存中心需要使用单独去重表。
库存中心:库存中心更改库存前,需要保证幂等性,同理,用去重表。
财务中心:完成入库之后,创建采购结算单,一个采购入库单对应一个采购结算单,采购入库单作为请求唯一标识。业务表唯一索引(唯一索引:采购入库单id)
2.2.3 采购结算单审核
提交采购结算单审核:因为只牵涉到修改状态的业务,类似于采购单审核,这里可以考虑不做幂等性。
采购结算单审核:
财务中心:审核采购阶段单“待审核”为已完成,使用状态机模式:
注意状态机模式有两种实现方法:1、先查询出业务对象,判断状态,不符合,返回,符合,执行直接不携带前一个状态的更新(update table set status=目标状态 where id=xxx)。
2、直接根据携带目标状态的更新:update table set status=目标状态 where id=xxx where status=目标状态前一个状态
wms中心:使用状态机模式. 更改“已审核”为“已完成“。
采购中心:更改采购单状态为:“已完成”。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。