购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

1.1 直面微服务架构

微服务架构首先表现为一种分布式系统(Distributed System),而分布式系统是对传统单体系统(Monolith System)的一种演进。为了帮助读者更好地理解和掌握微服务架构的特点,本节先围绕从单体系统到微服务架构的演进过程进行展开,然后引出微服务架构的实施方法以及所应该具备的核心技术组件。

1.1.1 从单体系统到微服务架构

在软件技术发展的很长一段时间内,软件系统都表现为一种单体系统。时至今日,很多单体系统仍然在一些行业和组织中得到开发和维护。所谓单体系统,简单来讲就是把一个系统所涉及的各个组件都打包成一个一体化结构并进行部署和运行。单体系统存在一些固有的问题,在本节中,我们从这些问题出发来剖析微服务架构的诞生背景和特性。

1.单体系统存在的问题

图1-1展示的就是一个典型的单体系统,我们可以看到在应用服务器上同时运行着面向用户的Web服务层、封装业务逻辑的业务逻辑层和完成数据持久化操作的数据访问层组件,这些组件作为一个整体进行统一的开发、部署和维护。

图1-1 单体系统

单体架构简单且容易实现,但随着公司或者组织业务的不断扩张、业务结构的不断变化以及用户量的不断增加,单体架构面临着越来越多的挑战,已逐渐无法适应互联网时代的快速发展。让我们一起来分析一下。

对于大多数系统而言,架构设计是为了满足业务需求。衡量架构好坏与否的一个重要方面是看其面对复杂业务变更时所具有的灵活性,也就是我们通常所说的可扩展性(Extensibility)。可扩展性是指系统在经历不可避免的变更时足够灵活,针对提供这样的灵活性所要付出的成本进行平衡的能力。所谓可扩展,扩展的是业务。当向一个现有系统中添加新业务功能时,如果不需要改变原有的业务体系而只需把新功能封闭在一个新的模块或子系统中就能完成整体业务的升级,我们就可以认为该系统具有较好的可扩展性。显然,单体系统不具备良好的可扩展性,因为对系统业务进行任何一处修改,都需要重新构建整个系统并进行发布。单体系统内部没有根据业务结构进行合理的拆分是导致其可扩展性低下的主要原因。

前面讲到单体系统的可扩展性很差,实际上它的可伸缩性同样也有问题。所谓可伸缩(Scalability),伸缩的是性能,即当系统性能出现问题时,如果我们只需要简单地添加应用服务器等硬件设备就能避免系统出现性能瓶颈,那么该系统无疑具备较高的可伸缩性。通常,我们会考虑采用水平伸缩的方法实现可伸缩性。当考虑水平伸缩时,一般的做法是建立一个集群,在集群中不断地添加新节点,然后借助前端的负载均衡器,将用户的请求按照某种算法分配到不同的节点上。但是,由于单体系统的所有程序代码都运行在服务器上的同一个进程中,内存密集型和CPU密集型并存,也就要求所有应用的服务器都必须有足够的内存和强劲的CPU来满足需求。这种方法成本会比较高,而且资源利用率通常都比较低下。

以图1-2所示内容为例,单体系统中的组件A的负载已经达到了80%,也就是到了不得不对系统的运行能力进行扩容的时候,但同一系统的另外两个组件B和C的负载还没有到其处理能力的20%。由于单体系统中的各个组件是打包在同一个运行包中的,因此虽然通过添加一个额外的系统运行实例可以将需要扩容组件的负载降低一半,但是显然其他组件的利用率变得更为低下,造成了资源浪费。另外,对于那些需要保持类似会话(Session)数据的需求而言,扩容之后的运行机制在如何保持各个服务器之间数据的一致性上也存在较大的实现难度。

图1-2 单体系统的可伸缩性问题

最后,我们需要认识到,在软件开发过程中,代码腐化在一定程度上是一种不可避免的现象。在单体系统中,由于缺乏合理的业务和技术实现边界,随着产品业务功能的增多,当出现缺陷时,有可能引起缺陷的原因组合比较多,这会导致分析缺陷、定位缺陷、修复缺陷的成本相应增加,也就意味着缺陷的平均修复周期可能会延长,从而影响产品的正常迭代和演进。同时,随着功能不断叠加,单体系统的代码结构也日益复杂,修复一个缺陷的同时还有可能引入其他的缺陷,在很多技术团队并不具备完善的持续集成(Continuous Integration, CI)和持续交付(Continuous Delivery, CD)能力的客观条件下,很可能导致出现问题越修越多的不良循环。

针对以上集中式单体系统普遍存在的问题,基本的解决方案就是微服务架构系统的合理构建。

2.微服务架构的特性

软件工程大师Martin Fowler在“Microservices”一文中提到,微服务架构具有服务组件化、按业务能力组织服务、去中心化和基础设施自动化等核心特性。

组件(Component)是一种可独立替换和升级的软件单元。在日常开发过程中可能会设计和使用很多组件,这些组件可能服务于系统内部,也可能存在于系统所运行的进程之外。而服务就是一种进程外组件,服务之间利用HTTP完成交互。服务组件化的主要目的是服务可以独立部署。如果你的应用程序是由一个运行在独立进程中的很多组件组成的,那么对任何一个组件的改变都将导致必须重新部署整个应用程序。但是如果你把应用程序拆分成很多服务,显然,通常你只需要重新部署那个改变的服务。在微服务架构中,每个服务运行在独立的进程中,服务与服务之间采用轻量级通信机制进行交互。

当寻找把一个大的应用程序进行拆分的方法时,研发过程通常都会围绕产品团队、UED(用户体验设计)团队、App前端团队和服务端团队展开,这些团队也就是通常所说的职能团队(Function Team)。当使用这种标准对团队进行划分时,任何一个需求变更,无论大小,都将导致跨团队协作,从而增加沟通和协作成本。而微服务架构下的划分方法有所不同,它倾向于围绕业务功能的组织来分割服务。这些服务面向具体的业务结构,而不是面向某项技术能力。因此,团队是跨职能的(Cross-Functional)特征团队(Feature Team),包含用户体验、项目管理和技术研发等开发过程所要求的所有岗位和技能。每个服务都围绕着业务进行构建,并且能够被独立部署到生产环境。

集中式系统的一个好处是技术的标准化,但采用微服务的团队更喜欢不同的标准。把集中式系统中的组件拆分成不同的服务,我们在构建这些服务时就会有更多的选择。对具体的某一个服务而言,应该根据业务上下文,选择合适的语言和工具进行构建。另外,微服务架构也崇尚对数据进行分散管理,让每个服务管理自己的数据库,无论是相同数据库的不同实例,还是不同的数据库系统。

许多使用微服务架构的产品或者系统,其团队拥有丰富的持续集成和持续交付经验。团队使用微服务架构构建软件需要更广泛地依赖基础设施自动化技术。

当然,在微服务中同样需要考虑网络传输的三态性、异构性、数据一致性和服务容错性设计等分布式系统所需要考虑的问题。随着本书内容的展开,会对这些特性进行详细的分析和讨论。

1.1.2 微服务架构的实施方法

构建微服务架构所需要做的不仅仅是构建服务本身。一个微服务系统的构建过程代表的是一种组织级别的活动,包括组织的人员架构、研发过程、技术体系和协作文化等多个因素。同样,微服务的运行时环境、错误处理机制和运维实践也是我们需要考虑的内容。本节中我们将针对如何构建微服务架构给出一套完整的系统方法,包括服务模型、实现技术、基础设施和研发过程等四个方面。

1.服务模型

服务建模是实现微服务架构的第一步,因为微服务架构与SOA(面向服务架构)、ESB(企业服务总线)等现有技术体系的本质区别就是其服务的粒度以及服务本身的面向业务和组件化特性。针对服务建模,我们首先需要明确服务的类别以及服务与业务之间的关系,从而明确服务的概念模型并给出服务的统一表现形式。同时,我们也需要借助诸如领域驱动设计(Domain Driven Design, DDD)中的限界上下文(Bounded Context)和领域事件(Domain Event)等技术合理划分微服务的边界,并剥离微服务与数据之间的耦合。建立服务模型最主要的工作是服务的拆分和集成。服务的拆分需要考虑拆分的维度、策略并管理服务之间的依赖关系、数据以及边界。而服务的集成则需要考虑采用合理的技术实现方式来满足轻量级服务通信的要求。关于领域驱动设计的核心概念和应用方式可以参考笔者所著的《DDD工程实战》一书。

2.实现技术

微服务的实现技术是构建微服务架构的重点。微服务架构具有分布式架构的基本特征,所以网络通信、事件驱动、服务路由、负载均衡、配置管理等因素同样是实现微服务架构的基础。另外,我们也需要考虑微服务架构实现上的一些关键要素,包括服务治理、数据一致性和服务可靠性等内容。关于技术体系的介绍是本书的重点,从第2章开始,我们将通过一个完整的案例系统全面介绍基于Spring Cloud Alibaba框架的技术实现过程。

3.基础设施

对于基础设施而言,包括服务的测试、服务的部署、服务的监控和服务安全性等都是需要开发人员考虑的内容。本书的主要目标在于阐述微服务的技术组件及其应用方式,但这些基础设施仍然是微服务架构整体蓝图的重要组成部分。

4.研发过程

微服务架构的构建过程中涉及业务结构、组织架构和研发文化等方面的内容,这些内容构成了开发团队的整体研发过程。讨论组织架构和软件开发的关系、构建跨职能团队、强调引入变化和敏捷思想有助于更好地落实微服务架构。

基于以上阐述的微服务架构构建的系统方法,开发人员可以通过掌握本书所介绍的各项微服务实现技术体系以及梳理现有架构的改造点,明确向微服务架构的转型方法,尝试并探寻微服务实施的最佳实践。

1.1.3 微服务架构的核心组件

对于开发人员而言,学习微服务架构的主体内容就是学习它的技术体系。同样,不同的开发工具和框架都会基于自身的设计理念给出对应的技术体系及其实现方式。抛开这些具体的工具和框架,我们可以基于目前业界主流的微服务实现技术提炼出一组技术组件,本节将对这组技术组件展开讨论。

1.服务治理

在微服务架构中,服务治理可以说是最为关键的一个技术组件,因为各个微服务需要通过服务治理实现自动化的注册和发现。

试想一下,如果系统中服务数量不是很多,那么我们有很多办法可以获取这些服务的IP地址、端口等信息,管理起来也不是很复杂。但当服务数量达到一定量级时,可能连开发人员自己都不知道系统中到底存在多少个服务,也不知道系统中当前到底哪些服务已经变得不可用。这时候,我们就需要引入独立的媒介来管理服务的实例,这个媒介一般被称为服务注册中心。图1-3展示了服务注册中心的作用。

图1-3 服务注册中心的作用

服务注册中心是保存服务调用所需路由信息的存储仓库,也是服务提供者和服务消费者进行交互的媒介,充当着服务注册和发现服务器的作用。诸如Dubbo、Spring Cloud/Spring Cloud Alibaba等主流的微服务框架都基于Zookeeper、Nacos等分布式系统协调工具构建了服务注册中心。

2.服务路由

现在,我们已经通过注册中心构建了一个多服务的集群化环境,当客户端请求到达该环境时,如何确定由哪一台服务器对请求做出响应就是服务路由问题。可以认为负载均衡是最常见的一种路由方案,常见的客户端/服务端负载均衡技术都可以完成服务路由。在Spring Cloud/Spring Cloud Alibaba等主流的微服务框架中也都内置了客户端负载均衡组件。图1-4展示了注册中心和负载均衡器之间的交互关系。

图1-4 注册中心与负载均衡器之间的交互关系

另外,负载均衡的出发点更多是提供服务分发而不是只解决路由问题,常见的静态、动态负载均衡算法也无法实现精细化的路由管理,这时候我们就可以采用路由规则。路由规则常见的实现方案是白名单或黑名单,即把需要路由的服务地址信息(如服务IP)放入可以控制是否可见的路由池中进行路由。同样,路由规则也是微服务开发框架的一项常见功能。

3.服务容错

对于微服务架构中的服务而言,服务自身会出现失败,还会因为依赖其他服务而导致失败。除了比较容易想到和实现的超时、重试和异步解耦等手段之外,我们还需要考虑针对各种场景的容错机制。图1-5展示了服务容错的常见技术。

业界存在一批与服务容错相关的实现策略,包括以失效转移为代表的集群容错策略,以线程隔离、进程隔离为代表的服务隔离机制,以滑动窗口、令牌桶算法为代表的服务限流机制,以及服务熔断机制。而从技术实现方式上看,在Spring Cloud中,这些机制部分包含在下面要介绍的服务网关中,而另一部分则被提炼成单独的开发框架,例如专门用于实现服务熔断的Spring Cloud Circuit Breaker。而在Spring Cloud Alibaba中也内置了专用的服务可用性框架Sentinel。

图1-5 服务容错的常见技术

4.服务网关

服务网关也叫API(应用程序编程接口)网关,它封装了系统内部架构,为每个客户端提供一个定制的API。在微服务架构中,服务网关的核心要点在于:所有的客户端和消费端都通过统一的网关接入微服务,在网关层处理所有的非业务功能。图1-6展示了服务网关的常见功能。

在功能设计上,服务网关在完成客户端与服务端报文格式转换的同时,可能还具有身份验证、监控、缓存、请求管理、静态响应处理等功能。另外,开发人员也可以在网关层制定灵活的路由策略。针对一些特定的API,我们需要设置白名单、路由规则等各类限制。业界主流的网关系统有很多,例如Spring家族的Spring Cloud Gateway就是其中的代表性实现框架。

图1-6 服务网关的常见功能

5.服务配置

在微服务架构中,考虑到服务数量和配置信息的分散性,一般都需要引入配置中心的设计思想和相关工具。与注册中心一样,配置中心也是微服务架构中的基础组件,其目的也是对服务进行统一管理,区别在于配置中心管理的对象是配置信息而不是服务的实例信息。图1-7展示了配置中心与注册中心之间的交互关系。

为了满足实现要求,配置中心通常需要依赖分布式协调机制,即通过一定的方法确保配置信息在分布式环境的各个服务中都能得到实时、一致的管理。我们可以采用诸如Zookeeper等主流的开源分布式协调框架来构建配置中心。当然,Spring Cloud和Spring Cloud Alibaba也分别提供了专门的配置中心实现工具Spring Cloud Config和Nacos。

图1-7 配置中心与注册中心之间的交互关系

6.服务安全

一般意义上的访问安全性,都是围绕认证和授权这两个核心概念来展开的。也就是说,我们首先需要确定用户身份,然后再确定这个用户是否具备访问指定资源的权限。站在单个微服务的角度,我们希望每次服务访问都能与授权服务器进行集成以便获取访问Token。而站在多个服务交互的角度,我们需要确保Token在各个微服务之间的有效传播。另外,在服务内部,我们可以使用不同的访问策略限制服务资源的访问。图1-8展示了基于Token机制的服务安全实现方案。

图1-8 基于Token机制的服务安全实现方案

为了实现对微服务的安全访问,我们通常使用OAuth2协议来实现对服务访问的授权机制,使用JWT技术来构建轻量级的认证体系。Spring家族也提供了Spring Security和Spring Cloud Security框架来简化这些组件的构建过程。

7.服务跟踪

在微服务架构中,当服务数量达到一定量级时,我们难免会遇到两个核心问题:一个是如何管理服务之间的调用关系;另一个是如何跟踪业务流的处理过程和结果。这就需要构建分布式服务跟踪机制。图1-9展示了分布式服务跟踪机制的核心功能。

分布式服务跟踪机制的建立需要完成调用链数据的生成、采集、存储及查询,同时需要对这些调用链数据进行运算和可视化管理。这些工作不是一个简单的工具和框架就能全部完成的,因此,在开发微服务系统时,我们通常会整合多个开发框架来完成整个链路跟踪。例如,在Spring Cloud中,就提供了Spring Cloud Sleuth与Zipkin的集成方案。

图1-9 分布式服务跟踪机制的核心功能 Zoj/EsIVX9TaCGC3wBnysWAGwRih3KY6r9FymyODRUJioaMT3glidh8DvE8A5Yu6

点击中间区域
呼出菜单
上一章
目录
下一章
×