今天这篇,我们主要分享应该如何定义一个微服务架构,怎么定义一个服务,微服务架构究竟又应该怎么进行服务拆分。
微服务架构
微服务架构的关键思想是如何进行功能分解。通过微服务架构你可以将应用程序构建为一组服务,而不是开发一个大型的单体应用程序。
一方面,将微服务架构描述为一种功能分解是有用的。另一方面,我们又要解决另外几个问题,包括:微服务架构如何与系统架构思想相结合?什么是服务?究竟怎么进行服务拆分?
这篇文章我们的主要目的就是通过解决这几个问题来帮助大家理解究竟应该怎么进行服务拆分。
系统架构思想
系统的架构是一种抽象的结构,它由系统的各个组成部分和这些部分之间的依赖关系构成。
系统的架构很重要的作用是它决定了应用程序的质量属性或能力。
传统的架构思想,架构的目标是可扩展性、可靠性和安全性。但随着大型互联网项目对系统迭代要求的效率更高,对架构的要求更高,能够快速安全地交付系统成为了一个重要指标。
微服务架构这种架构风格就应运而生,它可为应用程序提供更高的可维护性、可测试性和可部署性。
架构的意义
应用程序有两个层面的需求。
第一类是功能性需求,这些需求决定一个应用程序做什么。这些通常都包含在用例或者用户故事中。应用的架构其实跟这些功能性需求没什么关系。功能性需求可以通过任意的架构来实现,甚至是非常糟糕的大泥球架构。
第二类是非功能性需求,这就是架构的意义所在,我们把这类需求也称之为质量属性需求,或者简称为“能力”。这些非功能性需求决定一个应用程序在运行时的质量,比如可扩展性和可靠性。它们也决定了开发阶段的质量,包括可维护性、可测试性、可扩展性和可部署性。为应用程序所选择的架构将决定这些质量属性。
怎么定义服务
服务是一个单一的、可独立部署的系统组件,它实现了一些有用的功能。
服务具有API,为其客户服务的API封装了其内部实现。与单体架构不同,开发人员无法绕过服务的API直接访问服务内部的方法或数据。因此,微服务架构强制实现了应用程序的模块化。
服务的API封装了其内部实现。与单体架构不同,开发人员无法绕过服务的API直接访问服务内部的方法或数据。因此,微服务架构强制实现了应用程序的模块化。
微服务架构中的每项服务都有自己的架构,可能还有独特的技术栈。典型的服务往往都具有六边形架构。其API由与服务的业务逻辑交互的适配器实现。操作适配器调用业务逻辑,事件适配器对外发布业务逻辑产生的事件。
服务的松耦合
微服务架构的最核心特性是服务之间的松耦合性。
服务之间的交互采用API完成,这样做就封装了服务的实现细节。这允许服务在不影响客户端的情况下,对实现方式做出修改。松耦合服务是改善开发效率、提升可维护性和可测试性的关键。松耦合的服务更容易被理解、修改和测试。
我们通过API来实现松耦合服务之间的协调调用,这样就避免了外界对服务的数据库的直接访问和调用。服务自身的持久化数据就如同类的私有属性一样,是不对外的。
保证数据的私有属性是实现松耦合的前提之一。这样做,就允许开发者修改服务的数据结构,而不用提前与其他服务的开发者互相协商。这样做在运行时也实现了更好的隔离。
服务的角色
我们开发人员经常把一些通用的功能打包到库或模块中,以便多个应用程序可以重用它而无须复制代码。
在微服务架构中,我们可以通过把这些可能会更改的通用功能作为服务来实现,而不是共享库,我们通过对各业务方提供统一的服务来提高整体团队的研发效率。
服务的大小
微服务这个术语的一个问题是会将大家的关注点错误地聚焦在微上。它暗示服务应该非常小。实际上,大小不是一个重要的考虑因素。
更好的目标是将精心设计的服务定义为能够由小团队开发的服务,并且交付时间最短,与其他团队协作最少。理论上,团队可能只负责单一服务,因此服务绝不是微小的。
如果服务需要大型团队或需要很长时间进行测试,那我们应该可以考虑进行团队拆分或服务拆分。
另外,如果你因为其他服务的变更而不断需要同步更新自己负责的服务,或者你所负责的服务正在触发其他服务的同步更新,那么这表明服务没有实现松耦合。你构建的甚至可能是一个分布式的单体。
微服务架构把应用程序通过一些小的、松耦合的服务组织在一起。通过这样的架构提升开发阶段的效率,特别是可维护性、可测试性和可部署性,这也就让组织的软件开发速度更快。
根据业务能力服务拆分
微服务架构的策略之一就是采用业务能力进行服务拆分。业务能力是一个来自于业务架构建模的术语。业务能力是指一些能够为项目产生价值的业务模块。
特定业务的业务能力取决于这个业务的类型,比如电商系统的业务能力包括:订单模块、库存模块和发货模块等。
一旦确定了业务能力,就可以为每个能力或相关能力组定义服务。
围绕能力定义服务的一个关键好处是,因为它们是稳定的,所以最终的架构也将相对稳定。架构的各个组件可能会随着业务的具体实现方式的变化而发展,但架构仍保持不变。
根据领域驱动进行服务拆分
领域模型
领域模型以解决具体问题的方式包含了一个领域内的知识。它定义了当前领域相关团队的词汇表,领域驱动设计也简称DDD。
领域模型会被紧密地映射到应用的设计和实现环节。在微服务架构的设计层面,DDD有两个特别重要的概念,子域和限界上下文。
传统的企业架构建模方式往往会为整个企业建立一个单独的模型,DDD则采取了完全不同的方式。
在这样的模型中,会有适用于整个应用全局的业务实体定义,例如客户或订单。这类传统建模方式的挑战在于,让组织内的所有团队都对全局单一的建模和术语定义达成一致是非常困难的。
另外,对于组织中的特定团队而言,这个单一的业务实体定义可能过于复杂,超出了他们的需求。
此外,这些传统的领域模型可能会造成混乱,因为组织内有些团队可能针对不同的概念使用相同的术语,而也有些团队会针对同一个概念使用不同的术语。DDD通过定义多个领域模型来避免这个问题,每个领域模型都有明确的范围。
识别子域
领域驱动子域定义单独的领域模型,子域是领域的一部分,领域是DDD中用来描述应用程序问题域的一个术语。
识别子域的方式跟识别业务能力一样:分析业务并识别业务的不同专业领域,分析产出的子域定义结果也会跟业务能力非常接近。
FTGO的子域包括:订单获取、订单管理、餐馆管理、送餐和会计。正如你所见:这些子域跟我们之前定义的业务能力非常接近。
DDD把领域模型的边界称为限界上下文。限界上下文包括实现这个模型的代码集合。当使用微服务架构时,每一个限界上下文对应一个或者一组服务。
我们可以通过DDD的方式定义子域,并把子域对应为每一个服务,这样就完成了微服务架构的设计工作。