微服务架构模式作为单体应用和面向服务架构的可行替代方案,正在业界迅速崛起。由于这种架构模式仍在不断发展,业界对这种模式的内涵和实现方式存在很多困惑。本报告的这一部分将为你提供必要的关键概念和基础知识,以了解这种重要的架构模式的好处(和权衡),以及它是否是你的应用程序的正确模式。

模式描述

无论你选择什么样的拓扑结构或实现方式,有几个共同的核心概念适用于一般的架构模式。这些概念中的第一个是单独部署单元的概念。如 图 4-1 所示,微服务架构的每个组件都作为一个单独的单元进行部署,通过有效和精简的交付管道,提高可扩展性,以及应用程序和组件的高度解耦,使部署更加容易。

也许理解这种模式最重要的概念是服务组件的概念。与其考虑微服务架构中的服务,不如考虑服务组件,它的颗粒度可以从单个模块到应用程序的很大一部分。服务组件包含一个或多个模块(例如,Java 类),它们代表了一个单一目的的功能(例如,提供一个特定城市或城镇的天气)或一个大型商业应用的独立部分(例如,股票交易安置或确定汽车保险费率)。设计合适的服务组件颗粒度是微服务架构中最大的挑战之一。这一挑战将在下面的服务组件协调小节中详细讨论。
image.png

图 4-1. 基本的微服务架构模式

微服务架构模式的另一个关键概念是它是一个分布式架构,这意味着该架构中的所有组件都是相互完全解耦的,并通过某种远程访问协议(如 JMS、AMQP、REST、SOAP、RMI 等)进行访问。这种架构模式的分布式性质是它如何实现一些卓越的可扩展性和部署特性的。

微服务架构令人振奋的一点是,它是从与其他常见架构模式相关的问题中演变而来的,而不是作为一种等待问题发生的解决方案而产生的。微服务架构风格自然地从两个主要来源演变而来:使用分层架构模式开发的单体应用和通过面向服务的架构模式开发的分布式应用。

从单体应用到微服务架构风格的演进之路,主要是通过持续交付的发展来推动的,即从开发到生产的持续部署管道的概念,它简化了应用的部署。单体应用通常由紧密耦合的组件组成,这些组件是一个单独的可部署单元的一部分,这使得改变、测试和部署应用变得麻烦和困难(因此,在大多数大型 IT 商店中常见的 “月度部署” 周期的出现)。这些因素通常会导致脆弱的应用程序,每次部署新的东西都会损坏。微服务架构模式通过将应用分离成多个可部署的单元(服务组件)来解决这些问题,这些单元可以独立于其他服务组件进行开发、测试和部署。

导致微服务架构模式的另一条演进路径是,从实施面向服务架构模式(SOA)的应用程序中发现问题。虽然 SOA 模式非常强大,提供了无与伦比的抽象水平、异构连接、服务协调以及将业务目标与IT能力相协调的承诺,但它仍然是复杂、昂贵、无处不在、难以理解和实施的,而且对大多数应用来说通常是过犹不及。微服务架构风格通过简化服务的概念、消除协调需求、简化连接和访问服务组件来解决这种复杂性。

模式拓扑

虽然有几十种方法来实现微服务器架构模式,但有三种主要的拓扑结构是最常见和最流行的:基于 API REST 的拓扑结构、基于应用 REST 的拓扑结构和集中式消息传递拓扑结构。

基于 API REST 的拓扑结构对于那些通过某种 API(应用编程接口)公开小的、独立的个人服务的网站来说很有用。这种拓扑结构,如 图 4-2 所示,由非常精细的服务组件组成(因此被称为微服务),包含一两个模块,执行独立于其他服务的特定业务功能。在这种拓扑结构中,这些细粒度的服务组件通常通过单独部署的基于 Web 的 API 层实现的基于 REST 的接口来访问。这种拓扑结构的例子包括雅虎、谷歌和亚马逊提供的一些常见的基于云的 RESTful 网络服务。
image.png

图 4-2. 基于 REST 的 API 拓扑结构

基于应用 REST 的拓扑结构与基于 API REST 的方法不同,客户端请求是通过传统的基于 Web 或胖客户端的业务应用屏幕而不是通过简单的 API 层接收的。如 图 4-3 所示,应用程序的用户界面层被部署为一个单独的 Web 应用程序,通过简单的基于 REST 的界面远程访问单独部署的服务组件(业务功能)。这种拓扑结构中的服务组件与基于 API REST 的拓扑结构中的服务组件不同,因为这些服务组件往往更大、更粗略,并代表整个业务应用的一小部分,而不是细粒度的、单一行动的服务。这种拓扑结构常见于复杂程度相对较低的中小型商业应用。
image.png

图 4-3. 基于 REST 的应用拓扑结构

微服务架构模式中另一种常见的方法是集中式消息传递拓扑结构。这种拓扑结构(如 图 4-4 所示)与之前基于 REST 的应用拓扑结构类似,只是这种拓扑结构不使用REST进行远程访问,而是使用轻量级的集中式消息代理(如 ActiveMQ、HornetQ 等)。在研究这种拓扑结构时,不要将其与面向服务的架构模式混淆,也不要将其视为 “SOA-Lite”,这是非常重要的。这种拓扑结构中的轻量级消息代理并不执行任何协调、转换或复杂的路由;相反,它只是一个访问远程服务组件的轻量级传输。

集中式消息传递拓扑结构通常出现在较大的商业应用或需要对用户界面和服务组件之间的传输层进行更复杂控制的应用中。与前面讨论的简单的基于 REST 的拓扑相比,这种拓扑的好处是高级队列机制、异步消息传递、监控、错误处理以及更好的整体负载平衡和可扩展性。通常与集中式经纪商相关的单点故障和架构瓶颈问题通过经纪商集群和经纪商联盟(将一个经纪商实例分割成多个经纪商实例,根据系统的功能区域划分消息吞吐量负载)得到解决。
image.png

图 4-4. 集中式的信息传递拓扑结构

避免依赖性和协调性的问题

微服务架构模式的主要挑战之一是确定服务组件的正确颗粒度。如果服务组件的粒度太粗,你可能无法实现这种架构模式所带来的好处(部署性、可扩展性、可测试性和松散耦合性)。然而,如果服务组件的粒度太细,就会导致服务协调的要求,这将很快把你的精简的微服务架构变成一个重量级的面向服务的架构,其中包含所有的复杂性、混乱、费用和基于 SOA 的应用程序通常会出现的花哨。

如果你发现你需要在应用程序的用户界面或 API 层中协调你的服务组件,那么说明你的服务组件过于细化了。同样,如果你发现你需要在服务组件之间进行服务间通信来处理一个请求,那么你的服务组件有可能是太细粒度的,或者从业务功能的角度看,它们没有被正确地分割。

服务间的通信可能会迫使组件间发生不需要的耦合,可以通过共享数据库来处理。例如,如果处理网间订单的服务组件需要客户信息,它可以到数据库中检索必要的数据,而不是在客户服务组件中调用功能。

共享数据库可以处理信息需求,但共享功能呢?如果一个服务组件需要包含在另一个服务组件中的功能或所有服务组件共有的功能,有时你可以在整个服务组件中复制共享功能(从而违反了 DRY 原则:不要重复自己)。这在大多数实现微服务架构模式的商业应用中是一种相当普遍的做法,为了保持服务组件的独立性和分离部署,重复一小部分业务逻辑的冗余性。小的实用类可能属于这类重复代码。

如果你发现无论服务组件的级别如何,你仍然无法避免服务组件的协调,那么这是一个很好的迹象,说明这可能不是适合你的应用程序的架构模式。由于这种模式的分布式性质,要在服务组件之间维持一个单一的事务性工作单元是非常困难的。这种做法需要某种事务补偿框架来回滚事务,这给这种相对简单和优雅的架构模式增加了很大的复杂性。

一些思考

微服务架构模式解决了单体应用和面向服务的架构中的许多常见问题。由于主要的应用程序组件被分割成较小的、单独部署的单元,使用微服务架构模式构建的应用程序通常更加健壮,提供更好的可扩展性,并能更容易地支持连续的交付。

这种模式的另一个优点是,它提供了进行实时生产部署的能力,从而大大减少了对传统的每月或周末 “大爆炸” 生产部署的需求。由于变化通常被隔离在特定的服务组件中,因此只有发生变化的服务组件需要被部署。如果你只有一个服务组件的单一实例,你可以在用户界面应用程序中编写专门的代码,以检测一个活跃的热部署,并将用户重定向到一个错误页面或等待页面。另外,你可以在实时部署过程中交换服务组件的多个实例,以便在部署周期内实现连续可用性(这在分层架构模式下是很难做到的)。

最后需要考虑的是,由于微服务架构模式是一个分布式架构,它与事件驱动架构模式中的一些复杂问题相同,包括合同的创建、维护和管理,远程系统的可用性,以及远程访问认证和授权。

模式分析

下表包含了对微服务架构模式的常见架构特征的评级和分析。每个特征的评级都是基于该特征作为一种能力的自然十度,基于该模式的典型实现,以及该模式的一般特点。关于该模式与本报告中其他模式的关系的侧面比较,请参考本报告末尾的 附录 A

整体敏捷性评级:高

整体敏捷性是指对不断变化的环境做出快速反应的能力。由于独立部署单元的概念,变化通常被隔离在单个服务组件中,这使得快速和容易部署。此外,使用这种模式建立的应用程序往往是非常松散的耦合,这也有助于促进变化。

易于部署的评级:高

由于远程服务的细粒度和独立性质,微服务模式的部署特性评分非常高。服务通常被部署为独立的软件单元,因此能够在白天或晚上的任何时间进行 “热部署”。整体的部署风险也大大降低,因为失败的部署能够更快地被恢复,并且只影响正在部署的服务的操作,从而使所有其他的操作继续进行。

可测试性等级:高

由于业务功能的分离和隔离到独立的应用程序中,测试可以有范围,允许更有针对性的测试工作。对一个特定服务组件的回归测试比对整个单体应用的回归测试要容易得多,也可行得多。另外,由于这种模式下的服务组件是松散耦合的,从开发的角度来看,做一个改变而破坏了应用程序的另一部分的可能性要小得多,减轻了为一个小改变而测试整个应用程序的测试负担。

性能评级:低

虽然你可以通过这种模式创建性能非常好的应用程序,但由于微服务架构模式的分布式性质,总体而言,这种模式并不自然地适用于高性能的应用程序。

可扩展性等级:高

由于应用程序被分割成独立的部署单元,每个服务组件都可以单独扩展,允许应用程序的微调扩展。例如,股票交易应用程序的管理区可能不需要扩展,因为该功能的用户量很低,但交易安置服务组件可能需要扩展,因为大多数交易应用程序需要该功能的高吞吐量。

易于开发的评级:高

由于功能被隔离到独立的、不同的服务组件中,由于范围较小且被隔离,开发变得更容易。开发人员在一个服务组件中做出影响其他服务组件的改变的可能性要小得多,从而减少了开发人员或开发团队之间的协调需要。