用代码“读懂”代码:衡量开发交付质量(微服务度量之一)

本文涉及的产品
注册配置 MSE Nacos/ZooKeeper,118元/月
云原生网关 MSE Higress,422元/月
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
简介: 用代码“读懂”代码:衡量开发交付质量(微服务度量之一)

回顾软件开发的流程,从前期的业务需求分析,到产品设计,再到架构设计,通过层层迭代,让所有关于业务及系统的思考、意图和策略最终都通过开发人员的代码表述出来。代码成了这些活动的最终产出物。


可以说,一个系统的源代码就是一本,读懂这本,我们就知道这个系统的前世今生。当然,深入(自动化)分析源代码也可以衡量服务的开发和设计质量。


在实际的开发工作中,大都采用面向对象的编程方式。我们把真实世界的业务实体映射成软件中的对象,实体间的关系就演变成了对象间的继承、实现和引用关系。因此通过对源代码的分析,可以知道软件系统的一系列关系逻辑,包括系统的调用入口在哪,以及系统API的实现和继承关系、类方法之间的引用关系等。如图2.11所示,如果将图左边的代码关系用图形化的方式呈现出来,就可以获得图右边的调用链路关系图。这类关系图对我们快速梳理和理解系统的逻辑非常有帮助,在此基础上也可以对微服务的调用质量进行优化。


源码是一个宝库,包含了很多的内容。假如有个超人能够记住所有的源码并理解透彻,那么很多治理的难题都能迎刃而解。问题一出来,超人就能快速地定位问题所在。奈何现实中没有超人,全盘读懂源码既是脑力活也是体力活,将成千上万个核心类的调用关系梳理出来并画出关系图,没有核心程序员好几周的辛苦努力是搞不定的。


image.png


人力有穷时,最好的办法是通过某种自动化手段,自动提取源码中的元素,自动梳理这些元素之间的关系,简言之就是通过代码去理解代码


所幸,现在已经有一些能够对源码进行解析的工具和组件,JDT就是其中的典型代表。JDT的全称是Java Development Tools,是Eclipse的核心组件,主要用于Java程序的组织、编译、调试和运行等。在Java源码解析上,JDT提供了一个AST组件(Abstract Syntax Tree,抽象语法树)来做Java程序分析。通过AST,编译器会把代码转化成一棵抽象语法树,树上的每个节点代表一个代码元素(变量、方法、逻辑块等),同时针对节点的类型和属性解析提供完整的能力。


利用JDT-AST解析Java源码的基本能力展示如下所示。


image.pngimage.png


image.png


通过JDT-AST可以解析出某个类所有引用的其他类(import)列表、类变量列表、类函数列表、函数内变量列表和函数内逻辑块。有了这些基础信息之后,再遍历每个方法中的每一行,通过正则表达式可以获取此代码行所调用的变量及其方法。比如,针对下面的代码:


image.png


对上面的结果稍加处理,可知上述代码分别调用了变量params的put方法和变量remind的getIsAdded方法。基于这个结论,再根据类变量列表及函数内变量列表匹配到对应的类上,即可获得某个类方法调用其他类方法的情况。微服务本身即以类方法(或接口)的形式存在,因此,通过这种方式可以获得微服务之间的调用关系,具体解析过程如图2.12所示。


image.png


有了这些信息,就可以逐个遍历方法,扫描方法的每一行代码,通过前面识别出的类变量及方法变量,找出这些变量的对外调用,从而构建出某个类方法对其他类方法的调用关系。如果把源码库中所有微服务工程的源码都进行扫描,可以获得一个Map<string,list></string,list对象集合,Map的key是某个类方法,Value是其调用的其他类方法的集合(为了程序处理方便,可能还需要构建一个类似的被调用关系集合Map)。在此基础上对这个Map进行递归遍历,就可以找出所有这些类方法的调用链路关系,如图2.13所示。图中的F#Func1K#Func1是微服务的调用入口,一般都作为调用契约以接口的形式存在。在进行代码扫描时,要注意将其与实现类做关联(接口和实现类的关联关系可以通过AST获得。


image.png


把如图2.13所示的这些调用链路关系合并,可以构建一个如图2.11右边所示的完整的方法级别的调用矩阵,微服务间的调用是这个调用矩阵的一个子集。


图2.14是一个真实静态调用链的示例,以一个类方法为起点,找到它调用的所有其他方法,逐层遍历后,就能得到图中所显示的调用层级关系。图2.14-①是这种调用关系的文本描述,从图中可以清晰地看到方法间调用的先后和层级关系。


要注意的是类的实现和继承关系。接口类方法或者抽象类方法是没有具体实现逻辑的,所以在程序扫描时,还需维护类直接的继承和实现关系。接口方法往往用具体的实现类方法来代替,这样就能顺利地找到它的下一层引用关系。


如果引入诸如mxGraph这类图形化展示组件,可以将图2.14-①中类方法间的调用关系用一棵从上至下、从左至右的调用树图来展示,如图2.14-②所示。调用树上每一个节点就是一个类方法,节点间的箭头连线就是一个调用关系。通过JDT能够识别出方法注释,还可以将方法注释在每一个类方法节点的右边列出。如果系统注释完整,那么通过一张图就可以基本读清楚一个微服务入口方法的完整实现细节。


如果一个方法类的结构比较复杂,例如它有IF…ELSE关系或者FOR循环等嵌套调用关系,也可以用JDT识别,将这种关系在调用线条上列出。这样就能清楚地知道这是一种分支调用关系还是一种循环调用关系。



image.png


由于扫描的是所有相关工程的代码,一张图上就包含了所有层级的服务或系统之间的RPC调用关系。通过包名来对不同的业务层级(前台、中台、后台)进行识别,并为不同包名的图形单元赋予不同的颜色,通过颜色的区分可以清楚地知道一个方法的调用究竟涉及多少个系统,在每个系统中的入口是什么、出口又是什么等。


这里存在一个问题,就是如何将源码扫描获取到的类方法(微服务的API)与需求/开发任务管理系统中的UserStory和Task关联上?可以强制要求在微服务API入口方法(或者微服务类声明)的注解(例如JavaDoc)上标注UserStory和Task的ID,扫描源码时通过对注解的解析即可将方法和需求或任务进行关联。不用担心开发人员不标注或者忘了标注,因为我们可以通过比对需求列表和源码的映射关系来监控开发人员是否贯彻了注解标注规范,如果有需求没有找到对应的方法或API入口,即可自动通知相应的开发人员及时修改。


有了以上信息,通过对最终构建出来的大调用矩阵不同维度的分析,可以获得很多微服务的开发及设计质量方面的度量信息,包括请求的调用链深度、服务间的依赖程度、服务的粒度等。这些度量信息将会作为微服务治理的度量及判定依据。



小贴士


笔者另外准备了一个更完整的JDT-AST源码解析示例,能够详细展示如何通过对一个Java类文件的解析来获得类的相关调用关系,限于篇幅,就不在本书中贴出其详细源码了,请读者自行从本书的GitHub源码下载站点中下载并运行,体验解析过程。





相关文章
|
2月前
|
消息中间件 API 持续交付
后端开发中的微服务架构实践####
【10月更文挑战第21天】 本文深入探讨了微服务架构在后端开发中的应用,从基本概念出发,详细阐述了微服务的核心优势、设计原则及关键技术。通过实际案例分析,揭示了微服务如何助力企业应对复杂业务需求,提升系统的可扩展性、灵活性与可靠性。同时,也指出了实施微服务过程中可能面临的挑战,并提供了相应的解决方案和最佳实践。 ####
37 3
|
1天前
|
监控 JavaScript 数据可视化
建筑施工一体化信息管理平台源码,支持微服务架构,采用Java、Spring Cloud、Vue等技术开发。
智慧工地云平台是专为建筑施工领域打造的一体化信息管理平台,利用大数据、云计算、物联网等技术,实现施工区域各系统数据汇总与可视化管理。平台涵盖人员、设备、物料、环境等关键因素的实时监控与数据分析,提供远程指挥、决策支持等功能,提升工作效率,促进产业信息化发展。系统由PC端、APP移动端及项目、监管、数据屏三大平台组成,支持微服务架构,采用Java、Spring Cloud、Vue等技术开发。
|
1月前
|
运维 监控 Java
后端开发中的微服务架构实践与挑战####
在数字化转型加速的今天,微服务架构凭借其高度的灵活性、可扩展性和可维护性,成为众多企业后端系统构建的首选方案。本文深入探讨了微服务架构的核心概念、实施步骤、关键技术考量以及面临的主要挑战,旨在为开发者提供一份实用的实践指南。通过案例分析,揭示微服务在实际项目中的应用效果,并针对常见问题提出解决策略,帮助读者更好地理解和应对微服务架构带来的复杂性与机遇。 ####
|
1月前
|
消息中间件 运维 安全
后端开发中的微服务架构实践与挑战####
在数字化转型的浪潮中,微服务架构凭借其高度的灵活性和可扩展性,成为众多企业重构后端系统的首选方案。本文将深入探讨微服务的核心概念、设计原则、关键技术选型及在实际项目实施过程中面临的挑战与解决方案,旨在为开发者提供一套实用的微服务架构落地指南。我们将从理论框架出发,逐步深入至技术细节,最终通过案例分析,揭示如何在复杂业务场景下有效应用微服务,提升系统的整体性能与稳定性。 ####
43 1
|
1月前
|
消息中间件 运维 API
后端开发中的微服务架构实践####
本文深入探讨了微服务架构在后端开发中的应用,从其定义、优势到实际案例分析,全面解析了如何有效实施微服务以提升系统的可维护性、扩展性和灵活性。不同于传统摘要的概述性质,本摘要旨在激发读者对微服务架构深度探索的兴趣,通过提出问题而非直接给出答案的方式,引导读者深入
46 1
|
1月前
|
负载均衡 监控 API
后端开发中的微服务架构实践与挑战
本文深入探讨了微服务架构在后端开发中的应用,分析了其优势和面临的挑战,并通过案例分析提出了相应的解决策略。微服务架构以其高度的可扩展性和灵活性,成为现代软件开发的重要趋势。然而,它同时也带来了服务间通信、数据一致性等问题。通过实际案例的剖析,本文旨在为开发者提供有效的微服务实施指导,以优化系统性能和用户体验。
|
2月前
|
消息中间件 运维 开发者
后端开发中的微服务架构实践与挑战####
本文深入探讨了微服务架构在后端开发中的应用,从其核心概念、设计原则到实际部署过程中面临的挑战进行了全面剖析。不同于传统的单体应用,微服务通过将复杂系统拆解为一系列小型、独立的服务,提高了系统的灵活性和可维护性。然而,这种架构的转变也伴随着服务间通信、数据一致性、部署复杂性等新问题。本文旨在为开发者提供一套应对这些挑战的策略,同时分享一些成功案例,以期促进微服务架构的有效实施。 ####
|
2月前
|
缓存 负载均衡 API
后端开发中的微服务架构实践与挑战####
在数字化转型的浪潮中,微服务架构凭借其高度的可扩展性、灵活性及易于维护的特点,成为众多企业后端开发的首选架构模式。本文将深入探讨微服务架构的核心理念,通过具体案例分析其在实际应用中的实践策略与面临的挑战,为读者提供一份详尽的微服务架构实施指南。 ####
|
2月前
|
消息中间件 监控 API
后端开发中的微服务架构实践与挑战####
本文深入探讨了微服务架构在现代后端开发中的应用,分析了其优势、实施过程中的关键考虑因素及面临的挑战。不同于传统的单体应用,微服务通过拆分功能模块为独立服务,提升了系统的灵活性和可维护性。我们将从微服务的基本概念入手,逐步剖析其在真实场景下的应用案例,并讨论如何有效应对服务间通信、数据一致性等复杂问题,旨在为开发者提供一套实用的微服务落地指南。 ####
31 0
|
2月前
|
安全 测试技术 持续交付
后端开发中的微服务架构实践与挑战####
本文深入探讨了微服务架构在现代后端开发中的应用,通过一个虚构项目案例,详细阐述了从单体架构向微服务架构转型的过程、面临的挑战及解决方案。不同于常规摘要的概述性质,本文摘要旨在直接引入核心议题——如何有效实施微服务以提升系统的可扩展性、灵活性和容错能力,同时揭示转型过程中常见的技术陷阱与最佳实践策略,为读者提供实战指南。 ####
25 0
下一篇
开通oss服务