Page 146 - 《软件学报》2020年第11期
P. 146
3462 Journal of Software 软件学报 Vol.31, No.11, November 2020
that the method proposed in this study can significantly speed up the decision-making of microservice decomposition, reduce the
decision-making burden of developers and the final result is reasonable.
Key words: monolithic system; microservice; scenario-driven; bottom-up; decomposition
传统软件系统大多采用所谓的单体架构,即所有代码被统一构建和部署,数据集中化管理.随着需求的变更
和软件的演化,单体系统的规模往往会不断变大、复杂度越来越高、使用的技术逐渐过时,导致维护成本大幅
提升、新特性的交付周期延长.在过去几年里,大部分云计算基础设施都具备了弹性、自恢复和可伸缩的能力,
虚拟化和容器技术发展迅速,这些因素共同促进了微服务(microservices),一种区别于单体架构的软件架构风格
被广泛接受和应用.
微服务将一个大型、复杂的软件系统分解成一组独立运行、以轻量级通信机制进行交互的相对较小的服
[1]
务 .这些服务围绕业务功能进行构建,可以独立开发、测试、部署和更新,以此带来的好处包括系统架构的解
[1]
耦、单个服务的交付周期缩短、技术选型更灵活、可扩展性更好、复用性更高等 .Neal Ford 于 2018 年 12 月
[2]
发布的“微服务成熟度状态”报告 显示,在调查涉及的 866 个受访者中,超过 50%的人表示,他们的组织中有超
过一半的新项目使用了微服务,近 70%的人使用了容器作为微服务的部署方式,86%的人认为他们的微服务项
目已经取得了部分成功.这很大程度上说明微服务已经成为一种趋势,并成功运用于生产实践中.
在企业实践中,许多微服务系统都是在单体架构的遗留系统基础上,通过微服务拆分和改造形成的.微服务
相对于单体架构有诸多优势,但将已有的单体系统拆分成微服务并不是一件容易的事情,Netflix 公司花费了 7
[3]
年时间才完成从单体到微服务的架构迁移 .同时,不正确、不合理的微服务架构反而会加大系统调试和故障定
[6]
位的难度 [4,5] .Eric Evans 提出的“领域驱动设计(domain driven design)” 方法,由于其所强调的限界上下文
(bounded context)的概念能够自然地映射成微服务,被广泛用作微服务设计的指导原则.但这种方法缺乏正式的
[7]
建模语言和工具支持 ,要求架构师对业务领域有深入的了解,很难在短时间内得出合适的拆分方案.此外,实际
的单体系统往往规模庞大、年代久远、实现与文档偏差大,导致原设计文档不可信,加大了人工分析的难度.
针对以上问题,本文提出一种场景驱动、自底向上的单体系统微服务拆分方法.该方法基于测试驱动的理
念,通过监控典型应用场景测试用例的执行,动态分析获取单体系统运行时的方法调用和数据库操作信息,生成
系统的数据访问轨迹图.根据数据访问轨迹图对底层的数据表图进行加权和聚合,基于数据表之间的关联分析
生成数据库拆分方案,接着再自底向上进行搜索,产生相应的代码模块拆分方案.为了验证方法的可行性,本文
在使用已有工具 Kieker [8,9] 获取系统运行时数据的基础之上,开发了一个微服务拆分辅助工具 MSDecomposer,
并在多个开源软件系统上进行了经验研究.实验结果表明,这种方法得到的拆分结果合理,且能够显著加快微服
务拆分决策的速度,减轻开发人员的决策负担.
1 背景及相关工作
传统软件系统的模块化重构是软件工程研究领域的一个重要分支,早在 1972 年,Parnas 就提出了对系统进
行模块化解构的标准 [10] .随后,围绕着信息隐藏、高内聚低耦合等原则,依赖静态结构分析、性能数据分析、仓
库挖掘等手段,诞生了一系列软件模块化方法和工具 [11−14] .然而,微服务的模块化和重构作为微服务实践的一大
挑战 [15] ,目前仍然缺少实用的方法和工具支持 [16] ,相关研究主要集中在经验总结和方法论上.
Francesco 等人 [17] 对 18 位在工业界真实参与了微服务化迁移改造的工程师进行了访谈,将迁移过程分成了
逆向工程、架构转移和前向工程这 3 个子过程,分别总结了这 3 个子过程在具体实施时遇到的主要问题和挑战.
Taibi 等人 [18] 则将微服务化改造过程分成 3 种类型,包括现有功能的迁移、重新开发以及通过“绞杀模式”实现
新功能,并总结提出了一个迁移过程框架.Jonas 等人 [19] 在文献数据库中进行关键词搜索,筛选出 10 篇与微服务
拆分相关的论文,总结其中涉及的重构方法,并将方法分成了静态代码分析、元数据(架构描述、UML 图等)导
向、工作流数据(通信数据、性能检测数据等)导向以及动态微服务拆分(依据运行时环境、资源消耗等信息)
这 4 种类别,对开发设计人员在重构方法的选择上给予一定的决策指导.
在以“领域驱动设计”为指导原则的微服务拆分方面,前人已做出不少探索,但在设计之初,需要投入较多精