Java中怎么调用链和方法执行耗时统计
本篇内容主要讲解“Java中怎么调用链和方法执行耗时统计”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java中怎么调用链和方法执行耗时统计”吧!
bee-mite是我给这个项目取的一个名字,看下项目的目录,代码其实也不多。(现在获取sessionid的功能我还没做,这是很容易的,后面我会添加上去)
asmip包:
实现字节码插桩,在类加载之前对字节码进行修改,插入埋点。目前已经实现了业务代码调用链插桩,在方法执行之前拦截获取类名、方法名,方法调用的参数,在方法执行异常时,获取到异常信息。还实现了方法执行时间的埋点,在方法执行之前获取系统时间,发送一个日记事件,在方法执行结束之后获取系统时间,发送一个事件。
business包:
代码插桩过滤器,使用责任连模式,对字节码进行多次插桩。
ipevent包:
事件的封装,埋点代码抛出事件给线程池,线程池分派事件给监听器进行处理。
logs包:
提供事件监听器接口,具体实现交由使用者实现,我这里提供了两个默认的实现类,在logimpl包下,默认的实现类只是将日记打印,在控制台打印日记信息。
如何使用?我在项目中写了个测试模块,是个简单的web项目,一个控制器UserHander,一个service层的实现类UserServiceImpl,当客户端发送一个“/user/wujiuye/123”请求时,执行链就是UserHander的queryUser方法->UserServiceImpl的queryUser方法。
这是一个spring boot项目。给VM options设置参数,-javaagent:bee-mite.jar包的绝对路径,当然后面还要跟个参数,就是包名,要对bee-mite-webdemo项目中哪个包下的业务代码进行插桩,如“com.wujiuye”,就是对“com.wujiuye”包下的所有的类都进行插桩,当然我过滤掉了接口、静态方法,还过滤掉了get和set方法。
运行spring boot项目,在浏览器中输入url,观察看控制台打印的信息如下。
这是用到了asm、javaagent、责任连模式。因为字节码是插入到业务代码中的,当执行业务代码的时候会执行埋点代码,如果处理程序也在业务代码中进行那么这将是个耗时的操作,影响性能,拖慢一次请求的响应速度,所以当埋点代码执行的时候,我是直接抛出一个消息事件,让线程池分派消息给监听器处理事件,这样就可以执行耗时操作,比如将日记存储到数据库进行持久化,也可以使用redis存储,便于后期进行项目代码异常排查。
我在bee-mite模块的test包下写了两个测试类,其中UserServiceImpl就是插桩的目标,运行TestAop的main方法,会在项目的targer/classes目录下生成一个叫TargerProxy.class的文件,这个就是对UserServiceImpl插桩后的字节码文件。来看下对比,到底bee-mite都帮我们做了什么。
❖ 源代码
❖ asm对字节码进行插桩后
因为使用了责任链模式,会对代码进行两次插桩,目的就是为了后面容易扩展功能,相信看了对比你也能知道我的bee-mite都帮我插入了哪些代码,这些代码都是通过asm自己写字节码指令插入的。当然也不是很难,要说难就是try-catch代码块的插入了,没有文档看还是好难摸索出来的,visitTryCatchBlock方法的三个label的位置,以及catch块处理异常算是个难点,我最终通过在源码类中添加try-catch块然后javap查看字节码发现异常处理表
Exception table:
from to target type
0 27 30 Class java/lang/Exception
到此,相信大家对“Java中怎么调用链和方法执行耗时统计”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!