1.1 服务端架构的发展——从单体应用到微服务

1.1.1 单体应用

通常,一个应用的服务端的主要工作是执行业务逻辑,获取或更新数据并返回到客户端显示。在互联网发展的早期阶段,因为访问量小,业务也相对单一,所以Web应用的服务端通常把所有功能都打包在一起部署以节约成本,比如一个基于Java语言开发的应用,以war包形式部署在Web容器里,这就是常说的单体应用(Monolithic Application)。从软件工程的角度来看,单体应用是一个单一的软件结构,用户接口和数据访问代码都被整合在单一的程序单元里。而作为一个软件架构,单体应用被认为是非模块化的,这也是它的突出特点。

单体应用具有如下优点。

· 开发简单。一般开发工具或IDE是为开发单体应用而设计的,开发完即可使用,没有额外工作。

· 易于测试。不需要额外的环境、配置等,本地就可以进行测试。

· 易于部署。因为是单一的整体,所以直接将程序包部署在运行环境即可。

图1-1展示了一个典型的单体应用,展示层(HTML+JavaScript)、业务逻辑和数据访问都耦合在一起。我们不得不承认,单体应用在软件架构的发展史上占有重要的地位。即便是今天,在简单的业务场景下它依然是一种不错的选择。然而,随着业务规模逐渐变大,单体应用的弊端便突显出来。

图1-1 单体应用架构

· 各个业务模块耦合严重,很难保证某一个模块的修改不影响其他模块。

· 部署问题。应用变得臃肿后部署本身就成为一种困难。另外,改动任何一部分,都不得不重新构建和部署整个应用,这可能会中断与改动无关的后台任务或者是数据库事务。

· 扩展方式单一,只能通过水平扩展来提高整体的计算能力。但实际上各业务模块对资源的需求并不平均,不能按需独立扩展会造成资源的浪费。

· 开发效率不高。因业务和前后端代码的耦合,开发团队可能需要花费很多时间协调和集成。

1.1.2 多层结构

为解决上面列举的单体应用架构的问题,以分而治之思想为基础的解决方案产生了,这就是多层结构(Multi-Tier Architecture)。一个应用常被分为3层:接口层、业务逻辑层和数据访问层。

· 接口层。为客户端提供对应的访问接口。

· 业务逻辑层。系统的主要功能和业务逻辑部分,对输入和输出的数据进行业务处理。

· 数据访问层。为业务层提供底层数据库的访问能力。

图1-2展示了一个多层结构的数据流图。用户发送请求,依次传递给接口层、业务层再到数据访问层,获取数据后再依次返回。多层结构的体系利用了高内聚、低耦合的思想,解决了单体应用混沌的形态,具有以下优点。

图1-2 多层结构的数据流

· 降低了层与层之间的依赖关系,使原本的强依赖变成了松散耦合。

· 结构更加明确,也更易于复用。

· 降低了开发难度,开发人员可以只关注其中的一层。

· 当解决方案变更时,可以比较容易地替换某一层的实现,而不会影响其他层。比如数据库由MySQL变成MongoDB后,只需要修改数据访问层,其他层不受影响。

在这一时期,解耦是多层结构要解决的主要任务,比如我们很熟悉的MVC模式。然而,分层也必然带来其他的缺点,比如性能损失(原本可以直接访问数据库的操作现在需要通过中间层执行)或者涉及多层的级联修改等。

1.1.3 面向服务的架构

随着垂直应用(或子系统)越来越多,不同的应用之间不可避免地需要交互,于是面向服务的架构产生了,这就是我们通常所说的SOA(Service-Oriented Architecture)。它是指在分布式环境下,系统或者其组件可以在网络上通过通用协议调用另一个系统,使得多个系统彼此协作,它是令被调用系统成为调用者的服务。面向服务的架构被认为是一种演化,而不是革命。它延续了之前系统架构设计的最佳实践,把原本是数据孤岛的各个单体应用封装成服务,并通过标准的网络协议连接在一起,组成了更大的系统。

SOA架构中的各个子系统通过企业服务总线(Enterprise Service Bus,ESB)实现了松散耦合。ESB是构建SOA时所使用的关键技术,可以简单地理解为它是一个通信系统,为各个应用提供交互能力。在SOA体系中,它能够通过多种通信协议(如HTTP、RPC和SOAP等)连接并集成不同组件将其映射成服务。

SOA将不同系统模块封装成服务,以集中管理的方式提供系统之间的交互能力。通常具有如下特点。

· 将子系统或者大块业务逻辑作为服务。

· 服务之间松散耦合。

· 服务可重用、可组合。

· 中心化管理(ESB)。

图1-3展示了一个简单的SOA体系结构,不同的服务或者子系统通过ESB进行通信。

图1-3 SOA体系结构

1.1.4 微服务架构

有人认为微服务(Microservice)就是SOA的一种表现形式。如果从面向服务这个角度来讲,的确如此。两者在理念上有一些非常相似的特点,但它们之间依然有较大的不同。在微服务架构中,业务逻辑被拆分成一系列小而松散耦合的分布式组件,它们共同构成了较大的应用。每个组件都被称为一个微服务,而每个微服务都在整体架构中执行着单独的任务或负责单独的功能。每个微服务可能会被一个或多个其他微服务调用,共同协作来完成一个完整、复杂的业务逻辑。

图1-4展示了一个简单的微服务应用。整个业务被拆分成几个不同的服务,客户端通过API网关发送请求,业务数据被拆分到不同的数据库,只能由对应的服务进行访问。

图1-4 微服务架构

微服务架构具有如下特点。

· 服务的粒度较小,一个大型复杂的系统由多个微服务组成。

· 采用UNIX的设计哲学,某个服务只做一件事,是一种可以独立开发和部署的无状态服务。

· 通过服务实现组件化。不使用库(Library)而用服务来构建组件以便于独立部署。

· 微服务的开发团队小而内聚,可独立开发自己的业务,团队之间没有依赖。

· 去中心化的数据管理。每个服务有自己的数据存储。

· 不受语言、平台的限制(现实中一个大型的微服务应用往往是一个多语言开发的异构系统)。