https://blog.csdn.net/vincent_wen0766/article/details/113839442

场景题目:一个供应链系统中,存在商品、销售订单、采购这三个服务,销售订单服务和采购订单服务都需要依赖于商品服务。

  • 根据商品的型号/分类/生成年份/编码等查找订单;
  • 根据商品的型号/分类/生成年份/编码等查找采购订单

初期方案

严格按照微服务划分的原则将商品相关的职责放在商品系统中。因此,在查询订单与采购订单时,如果查询字段包含商品字段,需要按照如下顺序查询:

  • 先根据商品字段调用商品的服务,然后返回匹配的商品信息;
  • 在订单或采购单中,通过 IN 语句匹配商品 ID,再关联查询对应的单据

2021021722525543.png
存在的问题:

  1. 随着商品数量的增多,匹配的商品也越来越多,于是订单服务中包含IN语句的查询效率越来越慢
  2. 商品作为一个核心服务,依赖它的服务越来越多,同时随着商品数据量的增长,商品服务已不堪重负,响应速度也变慢,还存在请求超时的情况;
  3. 由于商品服务超时,相关服务处理请求经常失败

    数据冗余方案

    数据冗余的方案说白了就是在订单、采购单中保存一些商品字段信息。

调整架构方案后,每次查询时,就可以不再依赖商品服务了,提供两种方案

  • 每次更新商品时,先调用订单与采购服务,再更新商品的冗余数据
  • 每次更新商品时,先发布一条消息,订单与采购服务各自订阅这条消息后,再各自更新商品的冗余数据

问题:

  • 数据一致性问题: 如果订单与采购的冗余数据更新失败了,整个操作都需要回滚。这时商品服务的开发人员肯定不乐意,因为冗余数据不是商品服务的核心需求,不能因为边缘流程阻断了自身的核心流程
  • 依赖问题: 从职责来说,商品服务应该只关注商品本身,但是现在商品还需要调用订单与采购服务。而且,依赖商品这个核心服务的服务实在是太多了,也就导致后续商品服务每次更新商品时,都需要调用更新订单冗余数据、更新采购冗余数据、更新门店库存冗余数据、更新运营冗余数据等一大堆服务。那么商品到底是下游服务还是上游服务?还能不能安心当底层核心服务?

消息发布订阅方案

  • 商品无须调用其他服务,它只需要关注自身逻辑即可,顶多多生成一条消息送到 MQ
  • 如果订单、采购等服务的更新冗余数据失败了,使用消息重试机制就可以了,最终能保证数据的一致性

20210217230141734.png
存在的问题:

  1. 数据冗余,每个服务都需要冗余一份商品数据20210217230239863.png
  2. 每个依赖的服务需要重复实现冗余数据更新同步的逻辑
  3. MQ的消息太多了

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

    设计思路:

  4. 将商品及商品相关的一些表(比如分类表、生产批号表、保修类型、包装类型)实时同步到需要依赖使用他们的服务的数据库,并且保持结构不变

  5. 在订单采购、查询等服务时,直接关联同步过来的商品相关表
  6. 不允许采购、订单等服务修改商品表

20210217230728305.png

  • 商品无须依赖其他服务,如果其他服务的冗余数据同步失败,它也不需要回滚自身的流程;
  • 采购、订单等服务无须关注冗余数据的同步

此时问题又来了,如何实时同步相关表的数据呢?直接找一个现成的开源中间件就可以了,不过它需要满足支持实时同步、支持增量同步、不用写业务逻辑、支持 MySQL 之间同步、活跃度高这五点要求
有以下几款消息中间件支持:
20210217231108176.png