微服务在最近几年大行其道,很多公司的研发人员都在考虑微服务架构,同时,随着Docker容器技术和自动化运维等相关技术发展,微服务变得更容易管理,这给了微服务架构良好的发展机会。在做微服务的路上,拆分服务是个很热的话题。我们应该按照什么原则将现有的业务进行拆分?是否拆分得越细就越好?这里我想结合易企秀商城服务(以下简称商城)的实际情况谈谈服务拆分的策略和坚持的原则。

1.服务拆分策略

1.1根据业务能力进行服务拆分和定义

创建微服务架构的策略之一就是采用业务能力进行服务拆分。业务能力是一个来自于业务架构建模的术语。业务能力是指一些能够为公司(或组织)产生价值的商业活动。特定业务的业务能力取决于这个业务的类型。例如,易企秀商城现在的业务能力包括商品管理、订单管理、价格管理、各种配置管理等等。

识别业务能力

组织的业务能力通常是指这个组织的业务是做什么,它们通常都是稳定的。与之相反,组织采用何种方式来实现它的业务能力,是随着时间不断变化的。这个准则在今天尤其明显,很多新技术在被快速采用,商业流程的自动化程度越来越高。一个组织有哪些业务能力,是通过对组织的目标、结构和商业流程的分析得来的。每一个业务能力都可以被认为是一个服务,除非它是面向业务的而非面向技术的。

把商城的业务能力逐一列出来似乎也并不太困难,如下所示。

  • 商品管理

product management:商品基础信息管理(包括翻页H5、轻设计、长页、易表单等商品)

  • 价格管理

price management:商品价格管理,例如商品原价、折扣价、会员价和会员折扣价

  • 配置管理

config management:配置管理,管理商城各种banner图、角标、热门搜索词、导航栏等

  • 订单管理

order management:订单管理,消费者创建订单,运营管理订单

  • 分类属性管理

category management:管理商品的分类

attribute management:管理商品的属性

  • 其他

顶级能力包括供商品管理、价格管理、配置管理、分类属性管理和订单管理。当然还有其他的顶级能力,这里没有一一列举。大多数顶级能力都会分解为子能力。例如,配置管理被分解为五个子能力。接下来,我们将了解如何使用业务能力来定义服务。

从业务能力到服务

一旦确定了业务能力,就可以为每个能力或相关能力组定义服务。图1显示了商城应用程序从能力到服务的映射。决定将哪个级别的能力层次结构映射到服务是一个非常主观的判断。我对这种特定映射的理由如下:

  • 将价格管理映射到自己的独立服务,因为商品的价格虽然是商品的一个属性,但是变动频繁。
  • 将配置管理的子能力映射为多个服务,是因为每种配置都有自己的独特性。

图1:

微服务架构怎么拆分服务的 微服务架构拆分原则_微服务

 

 

 

围绕能力组织服务的一个关键好处是,因为它们是稳定的,所以最终的架构也将相对稳定。架构的各个组件可能会随着业务的具体实现方式的变化而发展,但架构仍保持不变。话虽如此,但是随着我们对应用程序领域的了解越来越多,它们可能会随着时间的推移而变化,特别是架构定义流程中的一个重要步骤是调查服务如何在每个关键架构服务中协作。例如,你可能会发现由于过多的进程间通信而导致特定的分解效率低下,导致你必须把一些服务组合在一起。相反,服务可能会在复杂性方面增长到值得将其拆分为多个服务的程度。

1.2根据子域进行拆分

领域驱动为每一个子域定义单独的领域模型。子域是领域的一部分,领域是 DDD 中用来描述应用程序问题域的一个术语。识别子域的方式跟识别业务能力一样:分析业务并识别业务的不同专业领域,分析产出的子域定义结果也会跟业务能力非常接近。商城的子域包括:商品、订单、搜索、配置、分类属性等等。正如你所见:这些子域跟我们之前定义的业务能力非常接近。图2 展示了子域和服务之间的映射,每一个子域都有属于它们自己的领域模型。

DDD 把领域模型的边界称为限界上下文(bounded contest)。限界上下文包括实现这个模型的代码集合。当使用微服务架构时,每一个限界上下文对应一个或者一组服务。换一种说法,我们可以通过 DDD 的方式定义子域,并把子域对应为每一个服务,这样就完成了微服务架构的设计工作。(根据DDD的子域设计服务,可以参阅:https://microservices.io/patterns/decomposition/decompose-by-subdomain.html

图2:

微服务架构怎么拆分服务的 微服务架构拆分原则_微服务_02

 

按子域分解和按业务能力分解是定义应用程序的微服务架构的两种主要模式。但是,也有一些有用的拆分指导原则源于面向对象的设计。

2.拆分的指导原则

单一职责原则( SRP)

软件架构和设计的主要目标之一是确定每个软件元素的职责。单一职责原则如下:

改变一个类应该只有一个理由。—Robert C. Martin

类所承载的每一个职责都是对它进行修改的潜在原因。如果一个类承载了多个职责,并且互相之间的修改是独立的,那么这个类就会变得非常不稳定。遵照 SRP 原则,你所定义的每一个类都应该只有一个职责,因此也就只有一个理由对它进行修改。

我们在设计微服务架构时应该遵循 SRP 原则,设计小的、内聚的、仅仅含有单一职责的服务。这会缩小服务的大小并提升它的稳定性。

闭包原则(CCP)

在包中包含的所有类应该是对同类的变化的一个集合,也就是说,如果对包做出修改,需要调整的类应该都在这个包之内。—— Robert C. Martin

这就意味着,如果由于某些原因,两个类的修改必须耦合先后发生,那么就应该把它们 放在同一个包内。也许,这些类实现了一些特定的业务规则的不同方面。这样做的目标是当业务规则发生变化时,开发者只需要对一个交付包做出修改,而不是大规模地修改(和重新编译)整个应用采用闭包原则,极大地改善了应用程序的可维护性。

在微服务架构下采用 CCP原则,这样我们就能把根据同样原因进行变化的服务放在一个组件内。这样做可以控制服务的数量,当需求发生变化时,变更和部署也更加容易。理想情况下,一个变更只会影响一个团队和一个服务。CCP 是解决分布式单体这种可怕的反模式的法宝。

单一职责原则和闭包原则是 Bob Martin 制定的十一项原则中的两项。它们在开发微服务架构时特别有用。在设计类和包时可以使用其余的九个原则。