微服务拆分的维度和策略

关于服务拆分的切入点,我们先从MartinL.Abbott所著《架构即未来》中所介绍的AKF扩展立方体出发寻找一些灵感,然后给出本文中关于服务拆分的两大维度。

1. AKF扩展立方体

AKF扩展立方体(Scalability Cube)是一种可扩展模型,这个立方体有三个轴线,每个轴线描述扩展性的一个维度(见下图),分别是:

  • X轴

代表无差别的克隆服务和数据,工作可以很均匀的分散在不同的服务实例上

  • Y轴

关注应用中职责的划分,比如数据类型、交易执行类型的划分

  • Z轴

关注服务和数据的优先级划分,如分地域划分

微服务拆分的维度和策略_第1张图片

以上X、Y和Z轴的划分可以概括为X 轴关注水平复制,Z 轴类似数据分区,而Y 轴则强调基于不同的业务拆分。理论上按照这三个扩展维度,可以将一个单体系统进行无限扩展。举例来说,比如用户预约挂号应用,一个集群撑不住时,分了多个集群,后来用户激增还是不够用,经过分析发现是用户和医生访问量很大,就将预约挂号应用拆成了患者服务、医生服务、支付服务等三个服务。三个服务的业务特点各不相同,独立维护,各自都可以再次按需扩展。

在上图中,Y轴就是我们所说的微服务的拆分模式,即基于不同的业务进行拆分。但在进行业务拆分过程中,我们发现业务往往与数据有较大耦合性,所以接下去我们把业务和数据结合起来对服务拆分的维度展开讨论。

2. 业务与数据

服务拆分存在两大维度,即业务与数据。业务体现在各种功能代码中,通过确定业务的边界,并使用领域与界限上下文、领域事件等技术手段可以实现拆分。而数据的拆分则体现在如何将集中式的中心化数据转变为各个微服务各自拥有的独立数据,这部分工作同样十分具有挑战性。

关于业务和数据谁应该先拆分的问题,可以是先数据库后业务代码,也可以是先业务代码后数据库。然而在拆分中遇到的最大挑战可能会是数据层的拆分,因为在数据库中,可能会存在各种跨表连接查询、跨库连接查询以及不同业务模块的代码与数据耦合得非常紧密的场景,这会导致服务的拆分非常的困难。因此在拆分步骤上我们更多的推荐数据库先行。数据模型能否彻底分开,很大程度上决定了微服务的边界功能是否彻底划清。

服务拆分的方法需要根据系统自身的特点和运行状态,通常分为绞杀者与修缮者两种模式。

1. 绞杀者模式

绞杀者模式(Strangler Pattern)最早由Martin Fowler提出,指的是在现有系统外围将新功能用新的方式构建为新的服务的策略,通过将新功能做成微服务方式,而不是直接修改原有系统,逐步的实现对老系统替换。采用这种策略,随着时间的推移,新的服务就会逐渐“绞杀”老的系统。对于那些规模很大而又难以对现有架构进行修改的遗留系统,推荐采用绞杀者模式。

绞杀者模式的示意图如下图所示,我们可以看到随着功能演进和时间的不断推移,老的遗留系统功能被逐步削弱,而采用微服务架构的新功能越积越多,最终会形成从量变到质变的过程。绞杀者模式在具体实施过程中,所需要把握的最主要一点原则就是对于任何需要开发的功能一定要完整的采用微服务架构,对于完全独立的新功能这点比较容易把握,而对于涉及到老业务变更的新功能则需要通过重构达到这一目标。

微服务拆分的维度和策略_第2张图片

2. 修缮者模式

修缮者模式就如修房或修路一样,将老旧待修缮的部分进行隔离,用新的方式对其进行单独修复。修复的同时,需保证与其他部分仍能协同功能。从这种思路出发,修缮者模式更多表现为一种重构技术。修缮者模式在具体实现上可以参考Martine Fowler的BranchByAbstraction重构方法,该重构方法的示意图如下图所示。

微服务拆分的维度和策略_第3张图片

从上图中,可以看到这种模式的实现方式可以分成三个主要步骤。

  • 抽象层提取

首先通过识别内部的待拆分功能,对其增加抽象接口层,同时对原有代码进行改造,确保其同样实现该抽象层。这样在依赖关系上就添加了一个中间层。

  • 抽象层实现

为抽象层提供新的实现,新的实现采用微服务方式。

  • 抽象层替换

采用新的实现对原有的各个抽象层实现进行逐步替换,直至原有实现被完全废弃,从而完成新老实现方式之间的替换。

 

如果对文章感兴趣,可以关注我的微信公众号:程序员向架构师转型,或扫描下面的二维码。

我出版了《系统架构设计:程序员向架构师转型之路》、《向技术管理者转型:软件开发人员跨越行业、技术、管理的转型思维与实践》、《微服务设计原理与架构》、《微服务架构实战》等书籍,并翻译有《深入RabbitMQ》和《Spring5响应式编程实战》,欢迎交流。

你可能感兴趣的:(微服务架构,微服务,系统架构)