浅谈基于静态分析的微服务划分
作者:高邱雅
评阅人:李家琦、宋雪菲
一、背景
随着互联网的发展,单体应用的功能逻辑交互越来越复杂,各个功能模块紧密耦合。这样庞大复杂的项目使得开发、测试、运维极度复杂,同时在保证弹性、扩展性、可维护性方面也困难重重[1]。为了能够有效的解决这样的问题,需要将这些单体应用迁移到微服务技术架构。在向微服务架构迁移的过程中,首先要面对的挑战就是对微服务的划分。由于单体系统功能结构复杂,使得我们获取微服务划分的特征信息变得更加的困难。因此本文提出了通过对单体应用代码的静态分析来获取应用的结构特征信息的方法,通过这种方法来为微服务迁移过程中的微服务划分提供决策依据。
二、微服务化
微服务结构是一种轻量级、微型化的开发和运维方式。与单体架构相比,每个微服务模块具有专一功能,可单独部署和维护[2]。正因为每个微服务模块的独立性,将单体应用中的各个功能模块解耦,实现以模块为单位的多节点部署,从而达到对瓶颈模块的单独扩展并可以根据不同的功能灵活采用不同技术栈的效果。
与单体应用的在同一个进程内进行功能模块交互相比,微服务化也带来了通信的复杂性。除了传输延迟,网络故障等因素外,微服务之间的交互频繁度也是重要的影响因素。因此,微服务边界合理的划分显得至关重要。我们应将耦合度高、通信频繁的模块划分到一个微服务中,来降低服务间的通信开销。
三、具体实现
要想合理的对单体应用进行微服务划分,首先我们要全面的获取单体系统的结构特征,然后依据功能模块间的交互特征和领域知识将功能划分到不同的微服务中,最后根据微服务设计的单一功能、高内聚、松耦合、减少微服务之间交互的设计原则确定微服务的边界[2]。本文就获取单体系统的结构特征和对特征交互信息的分析做重点讨论,主要以静态分析的方式来获取结构特征。
1、静态分析
静态分析也称为静态代码分析,静态分析是通过不执行程序只检查代码的方式来分析程序结构和方法之间的依赖关系。通过静态分析可以获得应用的功能函数和类之间的调用关系,包含了他们之间调用的次数,从而可以形成类层次关系、类间调用关系和函数间调用关系。
进行静态分析时,用到的工具主要是ASM,它是一个全功能java字节码操作与分析框架。主要思路是读取项目的字节码文件,获取每个类的方法调用信息,将调用类与被调用类,调用方法与被调用方法存为节点,他们之前的调用关系存为有向边,并对调用次数进行统计,作为边的值。
2、JPetStore案例分析
基于以上的静态分析方法,我们对于JPetstore项目进行了分析,得到其类调用图和函数调用图。下图为图1 类调用图:
从图1 类调用图中我们可以看出项目的结构是通过action层调用service层再调用mapper层。通过横向的调用链分析,可以将系统分为用户模块、订单模块和商品分类模块,在这几个模块内部交互密集,而他们之间交互较少。
由JPetstore的类调用图可见,JPetstore是结构规范的单体应用,我们从其包和类的特征就可以得到应用的结构特征,但是仍有一些早期的项目,将前端展示,数据操作和业务逻辑混杂在一起[2],此时我们就需要对其方法的调用关系进行研究。从方法的调用关系来确定各个功能模块。图2展示的是查询订单列表功能的方法调用图。通过方法调用图可以确定各个方法之间的耦合程度。
四、总结与后续工作
通过对单体应用使用静态分析技术,获取的相关特征信息给微服务的划分带来了一定的理论依据。这一课题值得我们进行深入研究,希望可以探索出科学全面的方法,为微服务的划分提供指导。
本文的不足之处在于目前只进行了项目结构特征的提取,只对小型的单体应用的调用图进行了简单的分析,其分析过程仍然需要更科学合理的分析方法。
接下来的工作我们将会对其分析方法进行更深入的研究,试图通过对调用图进行聚类分析,得到聚集的点的方式来获取微服务候选集。
参考:
[2] 任仲山, 王伟, 高楚舒,吴国全,陈伟,魏峻,黄涛.遗留应用微服务化迁移方法研究. 软件学报.http://www.jos.org.cn/1000-9825/0000.htm