APP下载

微服务软件架构设计模式及其应用

2021-08-05倪小璐王旭英边俊凯杨风暴

关键词:分片设计模式事务

倪小璐,王旭英,边俊凯,杨风暴

(1. 中北大学信息与通信学院,山西 太原 038507; 2. 医惠科技有限公司企业研究院,浙江 杭州 215000)

0 引言

随着物联网、云计算、人工智能等新型技术的快速发展,复杂软件系统协同参与者的扩增形成了软件生态系统(software ecosystems, SECO)[1].但日趋复杂的业务需求变化,会导致新模块和组件的引入、新数据流和接口的增加,使得软件的可靠性、扩展性和可维护性都面临着重大挑战,因此软件架构设计的合理性和规范性显得越来越重要.

随着软件生态系统中各子系统和组件之间调用关系复杂性由低到高,软件设计模型也从单体架构模型向面向服务架构模型和微服务架构模型转变.

1)单体架构模型

传统单体架构模型通常采用由表示层、业务逻辑层和数据访问层组成的三层模型,将所有业务场景的三层模型放在一个工程中,经过编译、打包,并最终发布[2].单体架构模型最大的优势是编程语言统一、开发简单快速、环境容易搭建,初期开发和运维总体成本低且见效快.但是随着功能需求增加与业务逻辑复杂化,单体架构软件采用不断改写源代码或增加子功能的设计模式,一方面造成业务系统在不断升级中成为“牵一发而动全身”的复杂形态软件,另一方面难以准确估计开发难度与开发成本.

2)面向服务架构模型

为了解决单体架构模型的伸缩性、扩展性和灵活性等问题,面向服务架构(service-oriented architecture,SOA)用松耦合的理念实现服务功能的拆分.企业服务总线(enterprise service bus,ESB)是SOA的具体技术方案[3],为各个应用系统之间的互联互通提供了一个基于网络的、中心化的连接中枢,通过一套标准化的协议适配器来支持应用之间在消息、事件、服务级别上动态地互联互通.ESB在数据集成、应用集成、流程集成、门户集成方面优势明显,但是仍旧面临单个拆分的模块可能依然比较大、无法实现更小服务单元的敏捷交付,以及服务与服务之间耦合性依然紧密等问题.

3)微服务架构模型

微服务架构在继承SOA体系架构松耦合理念的基础上,强调“业务的彻底组件化和服务化”[4].微服务架构与ESB最大的区别是省去了连接中枢,微服务架构中的不同服务通过“服务接口契约”来完成网络调用通信.因此,与传统单体架构模型相比,微服务架构模型具有“高内聚低耦合”特点:一是微服务架构中的单体结构可以独立开发,服务与服务之间耦合相对较弱,对某个服务进行开发、测试等操作,不会对其他服务产生影响;二是在微服务架构下的技术选型是去中心化的,每个服务内容简单,如果需要升级或转型面临的难度相对于传统架构大大减少;三是微服务架构下的单体结构具有很强的容错性,由于各模块之间相互独立,当架构中某些模块产生故障时,其他模块仍可通过一系列技术手段运行;四是微服务架构的松耦合大大降低了服务扩展的成本,不同类型的服务在个性化底层资源需求和波峰波谷访问周期条件下,可快速、灵活、个性化地进行弹性伸缩从而降低服务扩展成本[5].

微服务架构模型的设计一般采用面向服务开发(service-oriented development,SOD)理念[6],但是在架构设计、服务拆分、管理方法、服务治理等方面缺乏设计范式和具体的设计模式指导.本文首先阐述并总结了微服务架构的整体设计范式,然后详细阐述了微服务编排和组装、分布式事务设计、微服务拆分设计等关键设计模式,最后对基于微服务架构模式的智慧医疗系统进行了分析.

1 微服务架构整体设计范式

微服务架构不仅是软件设计架构的改变,还需要在组织架构、管理策略、测试运维等领域做出相应的调整.因此微服务架构整体设计是一项系统性软件工程,需要重点关注软件架构、功能拆分、管理方法、服务治理、技术选型、运维服务等相关过程.

1.1 微服务设计原则

微服务架构的设计理念是将传统的单一应用程序转变成为一套小型的服务组合,根据业务逻辑将单体架构拆分成多个服务,每一个微小的服务都具有单一职责且可以单独部署和运行[4].“微”,顾名思义为“小”,是将原有单体架构中冗杂的子系统拆分出来的微型服务,然而业界对“微”没有一个确切的定义.一般来说,只要符合领域驱动设计,可完成一件不可再分割的完整业务操作功能就可以被认为是符合微服务架构的“单一职责原则(single responsibility principle,SRP)”[7].针对微服务架构来说,适合独立成为一个微服务的原则包括:能维持业务持久性、有业务生命力的领域对象;调用频率非常高的功能单元;所处理的数据量大且增速快的功能单元等.

1.2 功能拆分原则

由于历史原因,很多软件系统都需要面临从单体应用架构向微服务架构转型的过程.单体应用的功能拆分策略可以通过以下4个步骤来完成:1)根据应用程序的需求,以描述服务之间协作方式的系统操作为方式,提炼各种关键请求.2)根据系统操作实现功能的分解.功能分解的策略有两种,一种是以业务为指引,将服务与业务能力相对应;另一种是以“领域”为单位,分解和设计服务.但两者都需要遵从围绕业务概念而非技术概念分解和设计服务的原则.3)确定每个服务的API.将每一个系统操作分配给服务,服务可以完全独立运行.4)确定服务间的通信机制.服务通信机制有两种,一种是基于同步请求/响应的通信机制,另一种是基于消息的异步通信机制.在实践中,还需要解决网络延迟、同步进程间通信导致的可用性问题、数据一致性问题、全局类阻碍拆分等具体问题.

1.3 服务治理原则

在微服务架构下,服务实例的运行环境和网络地址是动态变化的,因此服务发现机制就显得尤为重要.服务发现机制的核心是服务注册,根据发现操作的主体,有3种服务发现模式:服务端发现模式、客户端发现模式、服务网络发现模式(图1).1)服务端发现模式主要通过代理网关实现请求转发(分发)的作用,代理网关通过服务注册中心获取可用服务节点,并根据收到的请求与具体服务节点建立连接并取得结果.2)客户端发现模式取消了“代理网关”,服务调用方会通过SDK直接获取服务注册中心的相关信息,并直接与服务提供方建立连接,与服务端发现模式相比,该模式调用效率更高且部署成本也更低.3)服务网络发现模式将直连模式中的SDK拆分出来,并以独立进程的模式和微服务部署在同一个操作系统中,服务调用方和提供方的所有网络调用均通过服务网格控制器(service mesh controller)实现对接口地址和状态信息进行统一管理,本地的服务网格代理会负责完成服务的寻找、发现及网络代理请求的建立,使得应用程序不会感知服务网格代理的相关工作,让开发者将精力更多集中在业务逻辑上而非繁琐的服务间调用与流量管理上,因此该模式近年来被广泛使用.

a.服务端发现模式 b.客户端发现模式 c.服务网络发现模式

1.4 技术选型原则

随着云原生微服务技术的不断发展,微服务开发框架也日趋成熟,主流的微服务框架主要包括Dubbo、Spring Cloud、Kubernetes等[8].虽然3种框架都为开发者提供了微服务开发与治理框架,但事实上三者间也并非一统而论,在服务网关、资源配置管理、调用链监控、容错限流、服务注册等技术实现与机制上均各不相同[8].因此在技术选型原则上,应深入理解不同的行业或组织的自身系统业务,对整体业务进行合理的规划和分析,综合利用Dubbo的微服务治理优势、Spring Cloud的Java微服务开发架构优势、Kubernetes的微服务容器化运行底层资源管理与调度平台优势,灵活构建行之有效的微服务技术架构与技术栈,以构建高效、健壮、灵活、可扩展的微服务应用.

1.5 运维设计原则

微服务架构不仅改变了技术架构的设计和开发模式,通过与DevOps[9]理念的天然融合,也从根本改变了开发、测试、运维的管理方法.DevOps是一种方法论,通过定义一组过程、方法与系统,用于促进应用开发、应用运维和QA部门的沟通、协作与整合,最终实现研发、运维、质量一体化.微服务架构的运维设计原则是要构建标准化、规范化和自动化的研发流水线或工具链,实现计划、设计、开发、测试、发布和运维的紧密协同,通常包括测试用例管理、测试环境管理、自动化持续构建(CI)、持续部署(CD)、发布管理、负载测试、应用系统监测、反馈管理等.如图2所示.

图2 基于DevOps的开发运维一体化管理

2 微服务架构的关键设计模式剖析

2.1 微服务编排与组装设计模式

随着需要管理服务的增多,服务的高效编排与治理成了需要迫切考虑的问题,本文主要分析了3种微服务编排与组装设计模式.

1)编制模式(orchestration pattern)[10]

编制模式与传统BPM、ESB的思想很相似,实现方案多是同步进行的.首先通过一个统一全局或局部流程控制服务,接收外部请求,依照业务逻辑规则与流程内部实现灵活抽象化的控制调用与编排,即依托流程中控依次按照特定的逻辑解析调用、组合、编排各个微服务,并最终完成整体流程处理逻辑.优势:流程控制服务或流程中控时时刻刻都知道每一笔业务或流程步骤究竟进行到了什么环节,因此对业务及服务进行有效的监控变得相对简单.劣势:流程控制服务或流程中控很容易控制较多的业务逻辑(微服务)且各业务逻辑呈现出繁杂的信息加工处理方式,在带来全局流程服务耦合度过高外,由于服务统一控制与编排会造成整体服务的灵活性降低,业务创新响应较弱,从而使得各个微服务退化为单纯的增删改查,容易失去自身价值.

2)编排模式(choreography pattern)

编排模式看作一种消息驱动模式,或者是订阅发布模式,实现方案多是异步的.在整体业务流程发起后,各个监听该事件的服务会主动获取消息,并实现对消息的处理与响应,并可以按需发布自己的消息以形成消息驱动.优势:服务间耦合度低,每个服务各司其职,可进行灵活而高效的个体服务变更,各服务间的逻辑关系简单透明.劣势:全局业务流程是通过订阅的方式来体现的,将服务间的抽象逻辑关系纳入到各自服务内涵中来,增加了单体微服务的额外交互开发设计考量,同时此种方式很难直接对每个服务进行有效的监控与管理,需要额外增加相应的监控系统,来保证业务顺畅进行.

3)API网关模式(API gateway pattern)

API网关模式可以看作是一种简单的接口聚合/拆分的方式.一项全局业务发起时,先到达网关,网关统一集中调用各微服务,并最终聚合/拆分需反馈的结果.优势:接口统一集中化管理,且对外接口相对稳定,可以利用LAN的带宽,弥补因特网的不足.劣势:只适合业务逻辑较为简单的场景或短流程,业务逻辑过于复杂时,网关接口耦合度及复杂度会急剧升高,使得各微服务的统一集中调用变得繁杂和臃肿,同时在整体微服务资源调度与任务运行中容易形成单点,造成一定的性能与可靠性影响.

上述3种微服务编排与组装模式,在企业进行微服务整体架构升级过程中,需要结合不同的行业特点、服务特点以及业务复杂度进行综合考量,如在扩展性上和工程化上,编制模式在一定程度上更优于编排模式,在一个业务域内编制模式更适用,而编排模式更适用跨业务域的流程.考虑到微服务服务编排的复杂性,不能完全依靠主观经验,构造一个编排框架至少要支持多种复杂抽象逻辑模型,应该采用元数据着色来自动适配服务参数的方法.

2.2 分布式事务设计模式

在微服务架构中,需保障各服务间的数据与信息处理层面的数据一致性与有效性[11],因此在数据操作与交换过程中应遵循ACID特性原则:

1)原子性(Atomicity)原则

单体微服务数据库本身的事务可以保证单分片操作原子性,可以参考XA协议的两阶段提交协议来保证所有一个事务的所有操作可以被作为一次原子操作,从而实现整个多服务集群内的分布式事务原子性.

由于分布式事务操作分散到存储的多个资源时,永远不能保证所有操作同一绝对时间发生或撤销.而在单个分片内的事务,本身保证事务的原子性,所以利用单分片事务特性,引入事务管理器,统一协调管理所有分片事务的提交或回滚.使用两阶段的目的是防止一阶段出现一个分片提交成功而另一个分片无法正常提交的情况,例如:分片2在收到commit指令前宕机的情况,分片2没有收到commit操作并且恢复时处于活跃的事务自动回滚.

2)一致性(consistency)原则

单体微服务数据库分片子事务可以保证分片内的数据一致性,在保证分布式原子性基础上加上数据强一致性方案,结合起来保证分布式一致性.

一致性设计目标保证任何情形下保证分布式操作不破坏所有分片数据的一致性状态,分片内可以通过数据库的事务状态保证,分片间通过分布式事务管理器(参考原子性设计方案)和强同步机制进行保证.

3)隔离性(isolation)原则

数据库锁和多版本并发控制(multiversion concurrency control,MVCC)可用于保证分片内事务隔离性,分布式隔离性需要MVCC机制将所有分片的历史版本数据暴露给代理,让代理在执行分布式事务时,实现一种类似全局MVCC的机制,从而得到可重复度级别(repeatable read)的分布式隔离性.

通过数据库的锁系统可以保证写隔离性,未提交的写操作不能够被其他事务重复修改;对于读隔离性,需要实现可重复读隔离级别读一致性,可采用基于对分布式读一致性综合考虑以及实现任意版本回溯的可能性,同构设计分布式多版本并发控制机制,保证即使事务运行在repeatable read或者read committed隔离级别下,所有的事务仍然可以读到分布式一致的数据.在设计中,通过建立全局分布式一致性版本信息,保证每个读事务都会读到全局一致性的数据而不阻塞任何写操作,以满足分布式隔离性设计.

4)持久性(duration)原则

分布式集群的所有单分片实例都需保证自身数据的持久性,保证已完成提交的分布式事务的所有变更都持久化,从而不会因故障导致丢失部分提交的数据.各分片数据持久性由分片数据库保证,分服务间可采用分布式数据库自身实现操作的原子性,结合分片内的数据持久性,以满足分布式数据持久性的需求.

2.3 微服务拆分设计模式

微服务拆分,通过对不同业务场景及技术依赖需建立相关原则,以保障服务拆分过程中的目标,包括:

1)单一职责原则

以业务为中心,让应用服务开发人员以业务创新为核心,在开发过程中更关注代码的业务逻辑编程.采用实现业务逻辑服务间的高内聚,服务边界的低耦合.微服务个体从业务内涵与场景创新上具备独立演进,独立创新的构建逻辑.

2)服务自洽原则

微服务在应用持续开发、持续集成、持续部署、持续运维的过程中保持团队与服务模块的独立性,包括开发语言的独立选择,但同时通过统一微服务架构在框架标准、接口服务标准保持一致并紧密协同.

3)去中心化原则

由于业务层与数据层对资源消耗的方式与趋势的差异化,促使业务逻辑与数据逻辑分层独立进行构造.实现业务逻辑与数据、会话解耦.

4)轻量级通信原则

在整体微服务框架需要支持并兼容跨语言、跨平台的通信方式及统一接口标准与协议标准.同时,微服务间的依赖关系通过模块化构架思想进行统一梳理、逻辑对应、模块化构建.

通过在对不同行业内的各类传统单体应用进行微服务拆分时,需要依据拆分优先级策略进行统筹,具体可包含新业务优先、通用服务优先、核心服务优先、边界明显的优先、独立属性优先.

3 智慧医疗微服务架构范例

近几年,微服务架构也开始进入医疗信息化领域.在技术上,微服务架构可实现功能解耦,使得医疗业务实现更敏捷,数据交互更灵活,自动化运维大幅提升.在业务模式上,微服务架构可以改变原有以HIS、EMR等大型信息软件为主体的模式,将医院信息系统进行功能拆分,以终端用户的实际业务需求为主导,将原有医疗信息系统以功能为边界的模式改变为以需求为目标的模式,最终以场景化服务的模式呈现给最终用户,更贴合医疗用户的实际工作需要,因此微服务架构正成为医疗信息化的朝阳.

如图3所示,在基于微服务的云HIS在患者挂号场景中,为了实现挂号服务中对患者基本信息服务的查询,按照微服务编排与组装设计模式,其算法设计如下:

图3 基于DevOps的开发运维一体化管理

1)患者基本信息服务PatInfoServ将自身服务注册至服务注册中心Register;

2)Register通过同步机制,向系统内所有容器{Pods}同步完整的服务注册表RegList;

3)患者挂号服务RegServ的实例RegServInst发起患者基本信息查询PatQuery;

4)查询RegServInst所在的本地API路由列表RegList,找到对应的服务提供方PatInfoServ;

5)RegServInst向PatInfoServ发起服务申请;

6)PatInfoServ在收到相关请求后,根据自身策略定位具体提供PatInfoServ服务实例PatInfo ServInst;

7)由PatInfoServInst和PatInfoServInst进行通讯和服务传递.

4 总结

微服务架构作为近年不断发展和成熟的软件架构技术,通过“高内聚低耦合”的核心理念,真正实现了面向业务的软件开发、运维、测试一体化管理流程[12].本文总结并提出微服务架构的整体设计范式,然后详细分析了微服务编排和组装、分布式事务设计、微服务拆分设计等关键设计模式,最后以智慧医疗系统中患者挂号场景为例给出微服务架构设计范例.随着微服务架构软件开发技术的不断发展,微服务在基础设施、信息交互、数据安全和网络安全等层面都面临着挑战[13],微服务架构设计范式还有更多的扩充空间.

猜你喜欢

分片设计模式事务
北京市公共机构节能宣传周活动“云”彩纷呈北京市机关事务管理局
上下分片與詞的時空佈局
设计模式识别的特征信息分类研究
利用状态归约处理跨分片交易的多轮验证方案①
“1+1”作业设计模式的实践探索
智慧图书馆环境下的融贯式服务设计模式研究
三维协同设计模式下的航天项目管理实践与展望
河湖事务
基于改进乐观两阶段锁的移动事务处理模型
基于模糊二分查找的帧分片算法设计与实现