上篇文章介绍了ApiHelp的架构设计和技术方案自主研发工具 【ApiHelp】-- 架构设计 和 技术方案,现在就来详细分析下Enhance组件的设计和实现。当前组件需要有一定的jvm字节码知识,更容易理解。
【功能设计】:
Enhance组件是ApiHelp核心组件之一,其主要工作就是通过ASM框架对目标程序的类方法进行字节码增强,实现零入侵式方法监控。
通过前几篇文章对ApiHelp的了解,大致分析下这边需要哪些增强工作:
1、方法执行耗时增强设计
方法执行耗时增强:用于监控当前方法执行时间。这里理解起来很简单,在API执行链路中,必然是由方法互相调用实现。如果需要清楚的展示API执行链路的各方法节点执行时间,必然需要对各方法进行监控增强。
增强思路:相信大家在做API日志时候,常用到 System.currentTimeMillis() 在方法的前后进行计算耗时。其实这里原理也差不多,但不同的是,为了更少的影响原程序的执行时间,我这里采用了缓存收集+后置日志记录的方式完成,大致设计如下:
这里就很简单,加入缓存使用到的就是简单的集合,所以性能损耗忽略不计,这里后续在Monitor组件中会详细介绍。
注意一点是,一个API从方法调用入口到结束,只会在入口方法结束时才会进行最终的耗时数据计算,以及完成日志的记录,这样几乎不会影响原API各方法耗时,我这里是通过请求线程信息,来识别是否当前请求,一次来判断是否方法调用结束。
2、方法异常设计
API在执行过程中遇到异常后抛出,此时API原链路受损,如果不做异常增强处理,无法正常的统计各方法耗时,因为可能在中间过程中就抛出了。
异常增强只需要在入口方法中进行捕获异常就行了,捕获到异常后我们可以按照@before方式正常结束调用,之后再抛出原异常信息。
3、SQL增强设计
SQL增强设计主要目的是监控,API执行过程中 各方法存在SQL调用时,完成监控。
监控思路,需要大家有一定的字节码知识,要知道程序再虚拟机中是字节码形式的,字节码指令就是方法执行过程中整个的栈过程,所以可以再执行过程中,通过识别当前执行的字节码指令是否为执行的SQL调用(比如jdbc的调用,或者公司内封装的调用),如果是,则在改字节码前后加入我们自己的字节码,用来记录SQL调用。
4、Http调用增强
这个原理和SQL增强原理一样,也是识别关键调用字节码指令,然后进行增强操作。
以上4中增强器完成后,就可以完成 各方法耗时、方法内SQL调用耗时、方法内SQL调用次数、Http调用耗时、Http调用次数、API执行耗时、API执行链路stace 等等等监控的实现。