Page 160 - 《软件学报》2020年第11期
P. 160
3476 Journal of Software 软件学报 Vol.31, No.11, November 2020
物种类对应的头像图片).
• MS2 包含了共享群组中的 4 张与宠物商品有关的表:category、product、item 和 inventory.
• MS3 包含了 4 张与订单有关的表,分别是 orders(记录订单详细信息,包括下单用户、下单时间、地址
等信息),orderstatus(记录订单状态),sequence(产生订单的全局唯一 ID)和 lineitem(订单中的商品项,每
一项包含一个 item 和对应的购买数量).
• MS4 不包含任何数据表和 SQL 语句,只有两个类及类中包含的方法.其中,PasswordEqualsValidator 类
实现了 Spring 框架的 Validator 接口,用于校验前端输入的新密码和重复密码是否相等.由于在校验后
直接返回结果,所以该类不会和数据库中的数据产生关联.第二个类是 Cart(购物车),由于数据库中没
有购物车这张表,所以该类始终保存在内存中,用户添加或删除购物车中商品的行为都只是对内存中
Cart 实例的操作,所以同样不会和任何数据表有关联.
对于 MS4,从设计角度上来说,可以选择将其中的 PasswordEqualsValidator 类和 MS1 合并、将 Cart 类和
MS3 合并,最终,Spring JPetStore 被分为用户、商品和订单这 3 个微服务.从类和接口的分配结果来看,和文献[27]
中的实验结果是一致的,这一定程度上验证了本文所提方法的正确性.
另外,即使拆分代价所占比例为 0,计算出的拆分方案也不需要拆分任何的 SQL 语句或者方法.原因是在生
成数据表图时,已经适当地增加了出现在同一条 SQL 的数据表之间的权重,所以拆分结果一定程度上倾向于少
拆 SQL 语句.
Spring JPetStore 是一个比较理想的系统,它的结构简单、实现规范,得出的微服务拆分方案并不需要拆分任
何的 SQL 语句、方法或者类.本文共实验了 4 个系统(如表 5 所示),其中,Exam++(模拟驾考系统)和 JeeSite(ERP
系统)这两个系统在同样没有任何反馈调整的情况下,计算出的拆分方案需要进行一定数量 SQL 语句、方法和
类的拆分.这种情况在现实中很常见,比如,由于原始设计或者实现的原因,一条 SQL 语句合并查询了多张数据
表,如果这些数据表最终需要拆分到不同的微服务中,那么这条 SQL 语句以及执行这条 SQL 语句的方法都需要
进行拆分,然后将本地方法调用转化成远程调用.文献[27]中的方法无法识别这种情况,因为它最小的拆分粒度
为类,即一个类和它所有的方法最终都只能归属于同一个微服务.另外,同样是从数据开始拆分,和 Levcovitz 等
人 [22] 通过人工识别子系统对数据表进行分类相比,MSDecomposer 实现了对数据的半自动化拆分,节省了人工
分析的时间.而和已有工具 Service Cutter [24] 相比,MSDecomposer 的输入准备只有粗粒度的场景级别的测试用
例,Service Cutter 需要使用者以固定格式编写所有的系统操作和用例描述,显然更加复杂、费时.
Table 5 Decomposition result of experimental systems
表 5 实验系统拆分结果
项目名称 数据表数量 微服务数量 需要拆分的类数量 需要拆分的方法数量 需要拆分的 SQL 数量
Spring JPetStore 12 3 0 0 0
zb-blog [43] 15 3 0 0 0
Exam++ [44] 15 5 2 4 4
JeeSite [30] 22 9 10 27 33
4.2 对比实验
本文挑选了 5 位具有微服务研究背景和开发经验的硕士研究生,让他们分别对本文的 4 个实验系统进行人
工分析,并给出数据表和代码的拆分方案.针对每个实验系统,参与者得到的信息包括系统的 Git 地址、数据库
地址以及网页访问地址.他们可以访问系统启动后的前台和管理员界面,了解系统的主要功能和流程,也可以看
到系统的数据模型和源码.
如表 6 所示,在分析每个系统的过程中,实验参与者会记录从开始到得出完整的数据表拆分方案、类划分
以及方法划分方案的时间.其中,类和方法的划分方案是指要明确每个类或每个方法归属于哪一个或哪几个服
务,允许实验参与者通过分析一部分代码后进行总体的估算.考虑到参与者不一定都是按照“先分析数据表、再
分析代码”这样的原则进行拆分,所以数据和代码拆分的时间可能会有重合的部分,还需要再记录总的分析时