由于个人工作原因,近期遇到多起因应用性能导致业务中断的事情。多次排查分析总结,发现是应用性能问题,当然性能的提现是多维度的,在这里就不赘述了。

主要关注在应用运行中断之前就发现它(事前处理),是很重要的。

要监控应用的性能,首先列出性能监控点,然后输出要关注的信息,最终根据信息进行数据分析得出性能瓶颈后进行持续优化改进,在问题爆发前将其扼杀在“子宫”里。

不同应用、不同场景下,监控点不尽相同,要关注的信息如何获取却是每个工程师都要思考的问题。

在接触javassist之前,有过几个方案,但发布了几版后发现实现方式太low、成本高、效率低等不足,其中包括:代码中嵌入日志、使用spring管理应用并使用aop、修改jar包源代码增加日志。

如果是一个新搭建的工程,以上方案可以在框架搭建过程中便包含进去,作为框架的基础能力随同应用一起发布。但是平台上应用很多,明显不是很适用,并且有些操作所带来的风险需要更多的工作量去规避。

于是,找到了她------javassist。

 

javassist的使用要借助于javaagent技术,接下来介绍如何使用javassist

1、获取javassit-3.20.0-GA.jar

2、创建类AgentTransformer并实现ClassFileTransformer接口,使用javassist API完成对源类字节码级别的修改

3、创建类AgentDemo,并增加premain实现public static void premain(String args, Instrumentation inst){ inst.addTransformer(new AgentTransformer()); }

4、创建MAINFEST.MF文件,内容如下:

Manifest-Version: 1.0
Premain-Class: AgentDemo
Can-Redefine-Classes: true
Can-Retransform-Classes: true

5、打jar包:main class指定使用MAINFEST.MF文件

 

 Java性能监控之javassist探索

Java性能监控之javassist探索

Java性能监控之javassist探索

6、实际应用--创建demo应用,引入两个jar包:javassist-3.20.0-GA.jar和javassistdemo.jar(上面打包出来的)

7、修改java启动参数

Java性能监控之javassist探索

8、运行应用程序,观察结果

System.out.println("This code is inserted before constructor sun/misc/URLClassPath$FileLoader$1");
System.out.println("This code is inserted after constructor sun/misc/URLClassPath$FileLoader$1");
This code is inserted before constructor sun/misc/URLClassPath$FileLoader$1
This code is inserted after constructor sun/misc/URLClassPath$FileLoader$1
System.out.println("This code is inserted before constructor com/hope/javassistapp/app/App");
System.out.println("This code is inserted after constructor com/hope/javassistapp/app/App");
System.out.println("This code is inserted before constructor sun/misc/Cleaner");
System.out.println("This code is inserted after constructor sun/misc/Cleaner");
System.out.println("This code is inserted before constructor java/lang/Enum");
System.out.println("This code is inserted after constructor java/lang/Enum");
This code is inserted before constructor sun/misc/URLClassPath$FileLoader$1
This code is inserted after constructor sun/misc/URLClassPath$FileLoader$1
System.out.println("This code is inserted before constructor com/hope/javassistapp/construct/JavassistDemo1");
System.out.println("This code is inserted after constructor com/hope/javassistapp/construct/JavassistDemo1");
This code is inserted before constructor com/hope/javassistapp/construct/JavassistDemo1
JavassistDemo1:自身构造函数输出内容
This code is inserted after constructor com/hope/javassistapp/construct/JavassistDemo1
This code is inserted before constructor sun/misc/URLClassPath$FileLoader$1
This code is inserted after constructor sun/misc/URLClassPath$FileLoader$1
System.out.println("This code is inserted before constructor com/hope/javassistapp/construct/JavassistDemo2");
System.out.println("This code is inserted after constructor com/hope/javassistapp/construct/JavassistDemo2");
This code is inserted before constructor com/hope/javassistapp/construct/JavassistDemo2
JavassistDemo2:自身构造函数输出内容
This code is inserted after constructor com/hope/javassistapp/construct/JavassistDemo2
System.out.println("This code is inserted before constructor java/lang/Shutdown");
System.out.println("This code is inserted after constructor java/lang/Shutdown");
System.out.println("This code is inserted before constructor java/lang/Shutdown$Lock");
System.out.println("This code is inserted after constructor java/lang/Shutdown$Lock");
This code is inserted before constructor java/lang/Shutdown$Lock
This code is inserted before constructor java/lang/Shutdown$Lock
This code is inserted after constructor java/lang/Shutdown$Lock
This code is inserted after constructor java/lang/Shutdown$Lock
This code is inserted before constructor java/lang/Shutdown$Lock
This code is inserted before constructor java/lang/Shutdown$Lock
This code is inserted after constructor java/lang/Shutdown$Lock
This code is inserted after constructor java/lang/Shutdown$Lock

 

 

输出结果中,黄色高亮部分是动态增加的代码造成的效果。

AgentDemo和AgentTransformer是agent工程下的,用于动态修改类使用。

package com.hope.agent;

import java.lang.instrument.Instrumentation;

import com.hope.transform.AgentTransformer;

/**
 * java agent 入口
 * @author hp
 *
 */
public class AgentDemo {

    public static void premain(String args, Instrumentation inst) {
        inst.addTransformer(new AgentTransformer());
    }
}
AgentDemo

相关文章:

  • 2021-10-06
  • 2021-06-21
  • 2022-12-23
  • 2021-11-07
  • 2022-01-12
  • 2022-02-11
  • 2021-11-08
  • 2021-07-27
猜你喜欢
  • 2021-11-13
  • 2021-10-03
  • 2021-08-17
  • 2021-12-25
  • 2022-02-06
  • 2021-05-09
相关资源
相似解决方案