微服务--数据同步

64 阅读4分钟

我正在参加「掘金·启航计划」

一、案例

在某商城系统中有如下三个表:

  1. 商品表
序号字段
1商品编号
2名称
3分类
4型号
5生产日期
6商品条码
  1. 订单表
序号字段
1订单编号
2下单时间
3下单用户
4总金额
  1. 子订单表
序号字段
1子订单编号
2商品编号
3单价
4数量
  1. 采购表
序号字段
1采购编号
2下单日期
3供应商
4总金额
  1. 采购子表
序号字段
1子采购编号
2商品编号
3单价
4数量

该商城按照微服务划分原则把商品相关的接口放在了商品服务中,把订单相关的接口放在订单服务中,把采购相关的接口放在采购服务中。并且后台管理系统具有如下查询功能:

  1. 根据商品型号、分类和生产日期、编码查询订单;
  2. 根据商品型号、分类和生产日期、编号查找采购单。

上面的这两种查询功能按照如下顺序执行:

  1. 先按照商品字段查询匹配的商品信息;
  2. 在订单服务中或者采购服务中查找对应商品的订单。

该方案存在一定的问题:

  1. 商品数量越多,查询出来符合要求的商品就越多,那么订单和采购服务查询的效率就会越来越低;
  2. 这里很明显,商品是一个核心服务,依赖这个核心服务的服务会越来越多,商品数量越来越多,那么商品服务就会出现请求超时的情况,进而造成依赖于它的服务也出现请求失败的问题。

二、数据冗余方案

要解决上一小节中的问题,我们首先会先到的方案是数据冗余。所谓的数据冗余就是在订单表和采购单表中增加商品信息的字段。这样每次查询订单和采购单的时候,就不需要依赖商品服务了,那么这里又出现了一个问题,如果商品更新了,怎么同步冗余数据。一般来说有两种方法:

  1. 每次更新商品后,再调用订单和采购服务更新冗余数据。这个方法会出现 数据一致性问题依赖问题。如果订单和采购服务的冗余数据更新失败,那么整个操作流程都要回滚,如果不进行回滚商品服务的数据和订单以及采购服务的冗余数据又不一致了,如果对整个流程进行回滚的话,就出现了非核心服务导致核心服务数据不正常的情况。从职责方面来说,我们更新商品信息关注的是商品服务,但现在又需要去调用其他的服务,显然不合理,并且后续如果被依赖的服务太多,那么每次更新商品服务就要去调用其他服务来更新冗余数据,增加更新失败的风险。
  2. 每次更新商品后,向MQ发布一条消息,订单和采购服务收到消息后更新各自的冗余数据。该方法商品服务不需要调用其他服务,只需要发送一条MQ即可,并且如果订单和采购服务的冗余数据更新失败了只需要使用MQ的重试机制即可,也不会影响到商品数据。但是这个方法依然存在几个问题,首先我们并不是只保存商品信息就行了,还需要保存商品分类和生产批号等冗余信息,那么就要订阅分类和生产批号等变更的消息;其次每个依赖商品服务的服务都需要实现冗余数据更新的逻辑,这样就造成了代码重复问题;最后这么多的消息订阅,就会出现MQ消息类型过多,调试的时候会搞不清楚消息被哪个节点消费了。

三、解耦业务逻辑的数据同步方案

为了解决上面的问题,又引入了解耦业务逻辑的数据同步方案,大致思路如下:

  1. 把商品和相关的表实时同步到需要一台和使用这些数据的数据库中;
  2. 查询采购和订单服务中的数据时,直接关联同步过来的商品表相关数据即可;
  3. 禁止采购和订单服务修改商品和相关的表。

这个方案避免了两个问题:

  1. 商品无需依赖其他服务,如果其他服务的冗余数据同步失败,也不需要回滚自身流程;
  2. 采购和订单服务不需要关注冗余数据同步。

但是这个方案的缺点是,增加了采购和订单数据库的存储空间。

四、总结

本篇文章简要介绍了微服务中数据同步的方案,在实际开发中具体使用哪种方案,视情况而定。