微服务,如何拆分服务是精髓 | 技术前沿
在《云原生基础架构最佳状态,就是没有基础架构》一文中,我们探讨了云原生基础架构的内涵及价值。   本篇我们讨论云原生的又一个重要理念——微服务。   其实之前在《理解了云原生,才能正确迎接云时代的到来》一文中已经简单阐释过微服务,它是区别于过去单一架构产品开发模式的一种新型方式,为的是持续交付这一云原生终极目标。可以说,微服务是云原生的灵魂。既然如此重要,本篇再来详细展开一下,包括什么是微服务、为什么需要微服务、微服务的设计原则等。

从历史发展看微服务起源

 

2005年,Peter Rodgers博士在云端运算博览会上提出微Web服务(Micro-Web-Service),将程序设计成细粒度的服务,以作为Microsoft下一阶段的软件架构。   2014年,Martin Fowler与James Lewis共同提出了微服务的概念,定义了微服务架构是以开发一组小型服务的方式来开发一个独立的应用系统,每个服务都以一个独立进程的方式运行,每个服务与其他服务之间使用轻量级(通常是HTTP API)通信机制。   Amazon是遇到“微服务”问题最早的公司。当年,Amazon面临着这样一个问题,当团队人数快速增长之后,沟通效率越来越低,如何提高效率,如何减少会议?最终想出来的办法是拆分服务,让各个团队关注不同的模块,让每个团队独立负责一个服务,通过契约化的接口缩小沟通范围,只要接口不发生变化,就不需要过分关注外部的变化。值得一提的是,当时Amazon也并不认为自己做的是微服务架构,直到看到Martin Fowler的文章。   所以,回过头看微服务,其实不是什么技术创新,而是开发过程发展到一定阶段对技术架构的要求,是在实践中不断摸索出来的。而这个过程离不开敏捷开发、持续交付、基础设施即代码等各种基础技术的发展,当然也离不开理论设想、实践摸索和理论框架的进一步完善。

何时采用微服务?

 

尽管微服务代表了先进的生产方式,但也并不意味着所有企业都适用。这其中有两个关键问题:一、什么时候开始微服务架构?二、如何决定服务的拆分粒度?   从一开始就选择微服务架构吗?最好不,产品初期优先选择单体架构。因为面对一个新的领域,对业务的理解很难在开始阶段就比较清晰。很多时候,从一个已有的单体架构中逐步划分服务,要比一开始就构建微服务简单得多。   另外,在资源受限的情况下,采用微服务架构风险较大,很多优势无法体现,性能上的劣势反而会比较明显。因为,微服务与敏捷开发、持续交付、基础架构等都密切相关。   至于服务拆分粒度,微服务架构中的微字,代表的并不是足够小,而应该是合适。如何理解合适?很难一开始就摸到七寸,也是一个磨合的过程,没有绝对的对与错。   如果实在找不到合适的依据,下面几条因素供参考,当然这些都是从通用角度考虑的,并不适用所有情况。一、团队规模,因为团队规模变大会出现决策瓶颈点;二、交付速度,拆分粒度越小,交付时受到的约束越小,速度越快;三、对占用资源的要求、对性能的要求、对一致性的要求、对架构演进速度的要求、对创新速度的要求等。   所以,何时采用微服务是一道实践题,没有标准答案,需要根据企业发展的实际情况做出判断。  

四个重要的设计原则

 

如何在通向微服务的道路上少走弯路,以下是几条通用原则。   一、垂直划分优先。   企业应该根据业务领域对服务进行垂直划分,因为水平划分有可能导致下面这些问题,比如调用次数更多,导致性能大幅下降;实现一个功能要跨越更多服务,沟通成本增加等。   二、持续演进。   服务数量快速增长带来架构复杂度急剧升高,开发、测试、运维等环节很难快速适应,会导致故障率大幅增加,可用性降低。非必要情况,应逐步划分、持续演进、避免服务数量的爆炸式增长。这等同于灰度发布的效果,先拿出几个不太重要的功能拆分出一个服务做试验,即便出现故障,影响范围也不会太大。   三、服务自治、接口隔离。   尽量消除对其他服务的强依赖,这样可以降低沟通成本,提升服务稳定性。服务通过标准的接口隔离,隐藏内部实现细节。这样可以让服务保持独立开发、测试、部署、运行,以服务为单位持续交付。   四、自动化驱动。   部署和运维的成本会随着服务的增多呈指数级增长,每个服务都需要部署、监控、日志分析等运维工作,成本会显著提升。因此,在服务划分之前,应该首先构建自动化的工具及环境。开发人员应该以自动化为驱动力,简化服务在创建、开发、测试、部署、运维上的重复性工作,通过工具实现更可靠的操作,避免微服务数量增多带来的开发、管理复杂度问题。  

怎么划分要根据业务模式而定

 

有了基本原则,下面讲一些具体的划分模式。   大的原则是基于业务复杂度选择服务的划分方法。当业务复杂度足够高的时候,应该基于领域驱动划分服务,当业务复杂度较低时,选择基于数据驱动划分服务。在做出选择的时候,还有一个参考指标是,团队以前是否已经有基于领域驱动开发业务的能力。   具体到每一种方式,数据驱动是一种自下而上的架构设计方法,强调的是数据结构,也就是通过分析需求,确定整体数据结构,根据表之间的关系划分服务。统筹,基于数据驱动划分服务的步骤如下:需求分析,抽象数据结构,划分服务,确定调用关系和业务流程验证。   领域驱动则是一种自上而下的架构设计方法,通过和领域专家建立统一的语言,不断交流,确定关键业务场景,逐步确定边界上下文。领域驱动更强调业务实现效果,认为自下而上的设计可能会导致技术人员不能更好地理解业务方向,进而偏离业务目标。通常,基于领域驱动划分服务的步骤如下:通过模型和领域专家建立统一语言,业务分析,寻找聚合,确定服务调用关系,业务流程验证和持续优化。   此外,还有一个很常见的服务拆分场景,那就是从已有单体架构中逐步划分服务。之所以说很常见,是因为很多场景下,并非从开始阶段就采用微服务架构,而是随着业务不断发展才逐步走向微服务。这种情况下,划分服务的步骤如下:前后端分离,提取公共基础服务(如单点登录)、不断从老系统中抽象出服务、垂直划分优先,适当水平切分。  

实施先决条件

 

就如前面所说,微服务与很多基础技术的发展紧密相关,这决定了要迈向微服务有一些必要前提。这其中主要有两个先决条件,一是研发环境和流程的转变,二是拆分前先做好解耦。   具体而言,要准备微服务相关的环境和流程,可以通过以下几个方面建立基本的条件,包括自动化工具链、微服务框架、快速申请资源、故障发现反馈机制。至于研发流程的转变,是一个大工程,需要重新组建团队,以服务为核心,按照业务领域划分全功能团队,改变原有的研发流程、决策机制。例如,倡导敏捷文化、快速迭代,做更多的自动化测试,加强Code Review,给团队更多的自主决策权等。   关于解耦。在数学中,是指使含有多个变量的数学方程变成能够用单个变量表示的方程组,即变量不再同时影响一个方程的结果,从而简化计算。在软件世界里,解耦强调的是每个单元可以独立变化,尽量减少外界对系统内部的影响。解耦有几个关键词,包括状态外置、也就是无状态,去触发器、存储过程,通过接口隔离等。   总结一下,微服务作为云原生最重要的一项理念革新,本文只是讲了一些微服务的基本概念、原则,后续还将分享更多实操经验,包括微服务API该如何设计,微服务框架如何选择等,欢迎持续关注。   当然,百度云智能云也有云原生微服务应用平台(Cloud-Native Application Platform,简称CNAP),这是一个为企业提供应用托管和微服务管理能力的PaaS平台,可以帮助企业简化部署、监控、运维等应用生命周期管理工作,同时提供服务注册、服务治理、服务监控和调用链等微服务管理和运维能力,欢迎大家关注和使用。

 

本文参考资料 百度智能云官网, https://cloud.baidu.com/product/cnap.html。 CNCF官网, https://www.cncf.io/。 《云原生基础架构》,机械工业出版社,2018年9月第一版。 《持续演进的Cloud Native 云原生架构下微服务最佳实践》,电子工业出版社,2018年10月第一版。
共2条回复 最后由没在咖啡 回复于2020-03-23 09:30