读【微服务设计】(四)分解单块系统

1. 识别出接缝处(限界上下文)

单块系统不具备高内聚、低耦合的特点,所以分解的第一步需要很谨慎,首先就是要识别出接缝的位置,我们可以从接缝处抽取相对独立的一部分代码,修改这部分不会影响系统的其他部分,并且能够清理代码库以及成为服务的边界。

很多编程语言都有命名空间的概念,帮助我们把相似代码组织到一起,如Python/Java/Go等都有package概念,当我们识别出限界上下文后就可以通过pkg将它们分开维护。

2. 更有效率的分解

如果要分解一个较大的单块系统,那需要对分解的代码做一些优先级划分。

  • 如接下来的开发任务是针对库存系统,那么下一步就将库存接缝抽出来作为一个服务,使其成为一个自治单元,就会大大加速后期开发速度
  • 团队结构,假如一个系统是由不同团队共同维护,那么优先按团队独立服务会是一个好的做法,这样单个团队就能全权负责它们的代码库
  • 安全方面,若某个系统会对财务相关接口做安全审计和传输数据保护等措施,如果把这个服务分离出来,可以更好的对它做监控、传输数据保护以及静态数据保护等
  • 技术方面,假如推荐系统团队研究出一种新算法(使用另一种语言),如果能把这部分代码分离出来,就很容易在出现问题时重构和测试

3. 共享静态数据

假如系统要使用国家列表数据,那么在微服务架构中如果共享呢,有几种方式:

  1. 数据写入数据库一张表,所有服务都直接读取此表
  2. 将数据放入一个单独的服务中的静态文件中,其他服务调用这个服务提供的接口来读取

第一种方式在修改时不大方便,第二种是个人认为比较合理的,它在更新时只需修改上线一个服务的静态文件即可,因为没有更新服务代码,所以其他服务不用更新pkg信息。

这里你可能对更新静态文件的具体方法有疑问,是这样做的,我们将静态文件放在/static目录下,命名为countries_202006270920.txt,后面的数字就是更改时间,在更新时我们将具有带有最新更改时间的文件放到/static目录下,服务在读取时读最新的文件。

4. 尽量不要共享表

通常我们多个服务都会需要读取一个用户的信息,比如是不是会员,是否注销等等,最好的做好是独立一个用户服务,其他服务调用这个服务提供的接口来工作,这样才能更好的做资源隔离,以及践行单一职责原则。

5. 重构数据库

这一步我们要实施分离了,那么你想的是在某次发布中把单块系统直接变成两个服务吗?并且他们拥有各自的数据库表?

事实上,我会推荐你先分离数据库结构,暂时不对服务进行分离。

表分离后,对于原先的某个动作而言,对数据库的访问次数可能变多,因为以前只需要一个SELECT就能得到所有数据,现在则需要分别从不同的地方拿到数据,然后在内存中连接。还有,分成两个表结构会破坏事务完整性,这会对应用程序造成很大的影响,后面会继续讨论。先分离数据库结构而不分离服务的好处在于,可以随时选择回退这些修改或是继续这样做,而不影响服务的任何消费者。我们对数据库分离感到满意后,就可以考虑对整个服务做拆分了。

6. 微服务下的数据一致性

很遗憾,对于这个部分我没有看到作者提出具有较大可行性的方案,书中阐述了两种办法:

  1. 补偿事务或操作,就是立马重试或者通过定时任务来周期性的检查和消除数据库中的不一致,但补偿事务仍然有失败的可能性,而在需要同步的操作有两个,三个甚至更多时,定时任务会非常难以理解,后期维护时可能是噩梦。
  2. 分布式事务,这需要一个中心化的事务管理器工具来统一编配系统中运行的事务。作者提到的一个算法是两阶段提交,也同时提到了这个算法的诸多缺点,比如事务管理器具有单点故障,投票结束后的提交也可能会失败等等。

关于这个话题,我想还需要继续探索。

猜你喜欢

转载自blog.csdn.net/sc_lilei/article/details/106979886
今日推荐