在说微服务架构前,先来温习一下我们用了很多年的单体应用。
单体应用(Monolithic Applications)单体应用是指应用(application)的所有功能都集中在一个程序(program)中,尤其我们最早时候常提到的三层。
在项目初期,开发、测试和部署都可以快速而简单地展开。当然,在程序内部,开发人员也会采用一定的设计模式,保证系统架构的干净整洁。代码一般有以下特征:
隔离(保证核心业务代码的稳定性)- 保证代码与数据库隔离。核心业务逻辑代码不关心结果是如何存储,对数据库系统或表结构的修改不敏感。
- 保证代码与外部系统的隔离。我们不可避免地会依赖外部系统,外部系统接口的稳定性也在我们的控制范围之外。核心业务逻辑代码对此也应该是无感知的,需要被隔离。
- 保证代码的可测试性。由于对数据库和外部系统接口进行了隔离,我们可以对核心业务逻辑进行充分的自动化测试。
综上,保证核心业务逻辑代码与 Web 应用框架、数据库、外部系统接口、UI 的隔离。
依赖规则(实现隔离的主要手段)- 单项依赖:外部依赖内部,内部结构对外部无感知。比如,在外圈中构建的数据结构不能被内圈使用。
- 核心实体层:与业务有关,封装了最通用的对象、方法、或企业级的规则,它们可以在多种用例下共用。
- 用例层:封装应用级别的业务逻辑。
- 适配层:主要转换数据结构。用例层、框架层都使用它们最合适的数据结构。
- 框架层:这层主要是 WEB 框架、数据库。主要写些胶水性质的代码与内层进行通讯。
什么是 Monolithic Applications?作者列举了两个例子,一个是几年维护下来的应用程序;一个是有几百万行代码的应用程序。衡量 Monolithic Applications 的几个标准:
- 【开发】单个开发人员很难完全了解整个系统。
- 【开发】很多个软件工程师并行开发不同的功能时,会导致大量的冲突。
- 【开发】系统代码量大和结构复杂,采用新的语言或者框架的可能性越来越小。
- 【编译部署】编译时间长,启动时间长,导致持续部署(continuous deployment)变得不可行。
- 【编译部署】虽然每次只修改了部分功能,但是需要进行完整的项目测试,延长了测试时间。
- 【运行】系统的稳定性降低,某些微不足道的功能模块的 BUG,可能会导致整个单体应用 Crash。
以上问题可以归结为一个:团队无法展开敏捷开发和交付(As a result, agile development and delivery of applications is impossible)
对 Monolithic Applications 的一个形容词是 big ball of mud,大泥球。A big ball of mud is a software system that lacks a perceivable architecture. Although undesirable from a software engineering point of view, such systems are common in practice due to business pressures, developer turnover and code entropy.
单体应用的缺点随着业务的扩张,会逐渐严重。这个时候很多牛逼的公司就开始利用新的架构来解决这类问题了,那就是【微服务架构】,因为它的一些优势,可以更好的解决单体应用的问题。
什么是微服务架构微服务架构背后的中心思想是,将某些类型的应用程序分解为可协同工作的较小且可组合的部分时,它们的构建和维护变得更加容易。每个组件都是不断开发并单独维护的,因此应用程序只是其各个组成部分的总和。这与一个整体开发的传统“整体”应用程序形成对比。
作为一组模块化组件构建的应用程序更易于理解,更易于测试,并且最重要的是,在应用程序的整个生命周期内都易于维护。
它使组织能够实现更高的敏捷性,并能够极大地缩短对生产进行工作改进所需的时间。
事实证明,这种方法是优越的,特别是对于由具有不同地理位置和不同文化背景的开发人员团队开发的大型企业应用程序。
微服务架构也不是银弹,也有如下的优点和缺点:
优点- 它解决了单体应用所面临的复杂问题。
- 使大型的复杂应用程序可以持续交付和持续部署。--- 这是最重要的好处
- 每个服务都相对较小并容易维护。
- 服务可以独立部署和扩展。
- 可以实现团队自治,松散耦合。
- 可以更容易的采纳新的技术和实验新特性、功能等。
- 拥有更好的容错性,某一个服务故障隔离其他服务可以正常响应请求。
微服务的通用定义通常依赖于提供 API 端点的每个微服务,通常但不总是无状态 REST API,可以像标准网页一样通过 HTTP(S)访问。这种访问微服务的方法使开发人员易于使用,因为它们仅需要许多开发人员已经熟悉的工具和方法。
缺点- 服务的拆分和定义是一个挑战。
- 分布式系统带来的各种复杂性,使开发、测试和部署变得更加的困难。
- 部署跨越多个服务的功能时,需要谨慎的协调更多地开发团队。
- 开发者需要思考到底应该在应用的什么阶段使用微服务架构。(过早的使用,成本会增高)
所以说,微服务虽然能解决一些问题,但是也不是银弹。它也面临着更多的挑战和问题,比如常提到的分布式事务、服务的发现和治理、测试困难(因为技术栈比较多,不可能让测试掌握所有的语言吧)。
扩展 The Clean Architecture依赖规则
- 内圆代表了软件的不同领域。一般来说,越向内软件层次就越高。外圆是战术(机制),内圆是战略(策略)。推动整个架构运行最重要的是依赖规则。该规则是指源码只能向内依赖。内圆不知道外圆的任何信息。需要特别指出的是,在外圆中声明的东西不应被内圆的代码所提及,包括函数,类,变量,或者任何其他已命名的软件实体。同样的,外圆中使用的数据格式不应被内圆使用,尤其是如果这些格式是由外圆的框架生成的时候。我们不希望外圆有任何东西影响到内圆。
实体 Entities
- 实体封装了企业业务规则。一个实体可以是带有方法的对象,或者是一组数据结构和函数。只要实体在企业中可被许多不同的应用使用即可,其他的没什么关系。如果你不是企业级应用,而仅仅是写一个简单的应用程序,那这些实体可认为是应用对象的业务逻辑。它们封装了最基本的和高层的规则。它们在外部变化时几乎不变。举个例子,你不希望页面导航或者安全机制的更改去影响到业务逻辑,对吧?任何特定应用的更改都不应影响到实体层。
用例 Use Cases
- 这一层的软件包含了应用的具体业务规则。它封装和实现了系统所有的用例。这些用例编排实体的数据流入和流出,指导这些实体使用企业侧的业务规则来实现用例目标。
接口适配 Interface Adapters
- 本层的软件是一组适配器。适配器用于将最适用于用例和实体的数据格式,转换成最适用于类似 DB 或者 Web 的数据格式。举例来说,GUI 的 MVC 架构属于此层。表示器,视图和控制器都属于此层。模型更接近于数据结构,这些数据结构从控制器传递到用例,然后从用例返回给表示器和视图。
- 类似的,在此层,数据从最适用于实体和用户,转换到最适用于持久化框架,比如 DB。内圆的任何代码都不应该知道关于 DB 的信息。如果 DB 是 SQL 数据库,那么所有的 SQL 语句应该被局限于此层,特别是与数据库有关的层的各个部分。
- 同样的,在这一层中,还需要其他适配器来将数据从一些外部形式(如外部服务)转换为用例和实体使用的内部表单。
框架和驱动器 Frameworks and Drivers
- 最外层一般是由框架和工具组成的,比如 DB,Web 框架等等。一般来说,除了向内圆传递的胶水代码之外,在这个层中不会编写太多代码。这一层更多的是细节性的东西。Web 是细节,DB 是细节。我们将这些都放在外层以减少他们的危害。
跨越边界 Crossing boundaries
- 下角的图是如何跨越圆边界的例子。它表明了控制器和表示器与下一层的用例如何交互。注意控制流,它开始于控制器,通过用例,终结于表示器的执行。也要注意源码的依赖关系,它们总是向内指向用例。
- 我们通常使用依赖倒置原则(DIP)来解决这种明显的矛盾。比如像 Java 这种语言,我们可以安排接口和继承关系,这样源码可以在跨越边界的正确点上与控制流反向。
更多,可以阅读 https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html
扩展立方体这里着重提一下扩展立方体的概念。在《the art of scalability》这本书中描述的一个三维可扩展模型。
下面分别对 XYZ 三个维度进行阐述一下。
- X 轴:一般称为水平复制。通过克隆实例的方式进行扩展,保证可靠性与性能。这个比较常见就是同一个应用程序多台机器部署,通过类似于 Nginx 负载均衡。
- Y 轴:一般称为功能分解。通过分解不同的功能来实现扩展,服务单一职责,功能独立。这个就跟微服务架构沾边了。比如经常看到的一些对电商项目的拆分,用户模块、订单模块、商品模块、支付模块、评论模块等,都是功能拆解的一种使用。
- Z 轴:一般称为数据分区,数据独立,可靠性保证。常见的就是基于某一个 Key 进行取模分表、分库,将数据存储在不同的表或者库内,来提高性能。
本篇笔记仅仅是对比了传统的单体应用和微服务架构的优缺点。个人认为,对于微服务架构也不能过分的迷恋,因为既要考虑团队所处的阶段,也要考虑使用微服务架构以后面临的问题和挑战能否 hold 住。但是,对于“扩展立方体” 我们还是可以考虑使用的。
参考资料https://opensource.com/resources/what-are-microservices
https://microservices.io/patterns/microservices.html
https://www.nginx.com/blog/introduction-to-microservices/
文中部分图片来自网上,如有侵权,请联系删除。



